diff --git a/assets/main.js b/assets/main.js index de7c13b9d1..b39a7332a7 100644 --- a/assets/main.js +++ b/assets/main.js @@ -20,6 +20,7 @@ import KnownProducts from './vue/KnownProducts.vue'; import OpenReviews from './vue/OpenReviews.vue'; import ProductReviews from './vue/ProductReviews.vue'; import RecentReviews from './vue/RecentReviews.vue'; +import ReportMetadata from './vue/ReportMetadata.vue'; import ReviewSearch from './vue/ReviewSearch.vue'; import $ from 'jquery'; import {createApp} from 'vue'; @@ -54,6 +55,14 @@ window.cavil = { createApp(RecentReviews).mount('#recent-reviews'); }, + setupReportMetadata(pkgId, hasManagerRole, hasAdminRole) { + const app = createApp(ReportMetadata); + app.config.globalProperties.pkgId = pkgId; + app.config.globalProperties.hasManagerRole = hasManagerRole; + app.config.globalProperties.hasAdminRole = hasAdminRole; + app.mount('#report-metadata'); + }, + setupReviewSearch(pkg) { const app = createApp(ReviewSearch); app.config.globalProperties.currentPackage = pkg; diff --git a/assets/vue/ReportMetadata.vue b/assets/vue/ReportMetadata.vue new file mode 100644 index 0000000000..ebd83c4c21 --- /dev/null +++ b/assets/vue/ReportMetadata.vue @@ -0,0 +1,369 @@ + + + diff --git a/lib/Cavil.pm b/lib/Cavil.pm index 5d6f643492..6919380305 100644 --- a/lib/Cavil.pm +++ b/lib/Cavil.pm @@ -196,6 +196,7 @@ sub startup ($self) { $public->get('/reviews/recent')->to('Reviewer#list_recent')->name('reviews_recent'); $manager->get('/reviews/file_view//*file')->to('Reviewer#file_view')->name('file_view'); $public->get('/reviews/details/')->to('Reviewer#details')->name('package_details'); + $public->get('/reviews/meta/')->to('Reviewer#meta')->name('package_meta'); $public->get('/reviews/calc_report/' => [format => ['json', 'html']])->to('Report#calc', format => 'html') ->name('calc_report'); $public->get('/reviews/fetch_source/' => [format => ['json', 'html']])->to('Report#source', format => 'html'); diff --git a/lib/Cavil/Controller/Reviewer.pm b/lib/Cavil/Controller/Reviewer.pm index 8e487a23ff..9a3c941923 100644 --- a/lib/Cavil/Controller/Reviewer.pm +++ b/lib/Cavil/Controller/Reviewer.pm @@ -16,8 +16,9 @@ package Cavil::Controller::Reviewer; use Mojo::Base 'Mojolicious::Controller', -signatures; -use Mojo::File 'path'; -use Cavil::Licenses 'lic'; +use Mojo::File qw(path); +use Cavil::Licenses qw(lic); +use List::Util qw(first uniq); my $SMALL_REPORT_RE = qr/ (?: @@ -60,21 +61,103 @@ sub details ($self) { my $should_reindex = $self->patterns->has_new_patterns($pkg->{name}, $pkg->{indexed}); - my $products = $self->products->for_package($id); - my $requests = $pkgs->requests_for($id); - my $history = $pkgs->history($pkg->{name}, $pkg->{checksum}, $id); - my $actions = $pkgs->actions($pkg->{external_link}, $id); + $self->render(spec => $report, package => $pkg, should_reindex => $should_reindex); +} + +sub meta ($self) { + my $id = $self->stash('id'); + my $pkgs = $self->packages; + return $self->render(json => {error => 'Package not found'}, status => 404) unless my $pkg = $pkgs->find($id); + + my $spec = $self->reports->specfile_report($id); + my $type = first { length $_ } map { $_->{type} } @{$spec->{sub} // []}; + + my $main = $spec->{main}; + my $main_license = $main->{license}; + my $normalized_license = lic($main_license)->to_string; + my $package_license = $normalized_license || $main_license; + + my $version = $main->{version}; + my $summary = $main->{summary}; + my $group = $main->{group}; + my $url = $main->{url}; + my $has_spdx_report = $pkgs->has_spdx_report($id); + my $report = $pkg->{checksum} // ''; + my ($shortname) = $report =~ /:(\w+)$/; + + my $requests = $pkgs->requests_for($id); + my $products = $self->products->for_package($id); + + my $history = []; + for my $prev (@{$pkgs->history($pkg->{name}, $pkg->{checksum}, $id)}) { + my $entry = { + created => $prev->{created_epoch}, + external_link => $prev->{external_link}, + id => $prev->{id}, + result => $prev->{result} // '', + reviewing_user => $prev->{login} // '', + state => $prev->{state} + }; + push @$history, $entry; + } + + my $actions = []; + for my $action (@{$pkgs->actions($pkg->{external_link}, $id)}) { + my $entry = { + created => $action->{created_epoch}, + id => $action->{id}, + name => $action->{name}, + result => $action->{result} // '', + state => $action->{state} + }; + push @$actions, $entry; + } + + my (%docs, %lics, @package_files); + for my $sub (@{$spec->{sub} // []}) { + my $entry = { + file => $sub->{file}, + group => $sub->{group}, + licenses => [uniq @{$sub->{licenses} // []}], + summary => $sub->{summary}, + version => $sub->{version} + }; + push @package_files, $entry; + for my $line (@{$sub->{'%doc'}}) { + $docs{$_} = 1 for split(/ /, $line); + } + for my $line (@{$sub->{'%license'}}) { + $lics{$_} = 1 for split(/ /, $line); + } + } $self->render( - spec => $report, - package => $pkg, - products => $products, - requests => $requests, - history => $history, - actions => $actions, - should_reindex => $should_reindex, - has_spdx_report => $has_spdx_report + json => { + actions => $actions, + copied_files => {'%doc' => [sort keys %docs], '%license' => [sort keys %lics]}, + created => $pkg->{created_epoch}, + errors => $spec->{errors} // [], + external_link => $pkg->{external_link}, + has_spdx_report => \!!$has_spdx_report, + history => $history, + package_files => \@package_files, + package_group => $group, + package_license => {name => $package_license, spdx => \!!$normalized_license}, + package_name => $pkg->{name}, + package_shortname => $shortname, + package_summary => $summary, + package_type => $type, + package_url => $url, + package_version => $version, + products => $products, + requests => $requests, + result => $pkg->{result}, + reviewed => $pkg->{reviewed_epoch}, + reviewing_user => $pkg->{login}, + state => $pkg->{state}, + warnings => $spec->{warnings} // [] + } ); } diff --git a/t/error_review.t b/t/error_review.t index 589bc37573..a3baaacd49 100644 --- a/t/error_review.t +++ b/t/error_review.t @@ -49,7 +49,7 @@ $spec->spew($content); subtest 'Details after import (with login)' => sub { $t->get_ok('/login')->status_is(302)->header_is(Location => '/'); - $t->get_ok('/reviews/details/1')->status_is(200); + $t->get_ok('/reviews/meta/1')->status_is(200); $t->get_ok('/logout')->status_is(302)->header_is(Location => '/'); }; @@ -62,37 +62,28 @@ $t->app->minion->perform_jobs; subtest 'Details after indexing' => sub { $t->get_ok('/login')->status_is(302)->header_is(Location => '/'); - $t->get_ok('/reviews/details/1')->status_is(200)->text_like('#pkg-license', qr!Fake-Artistic!) - ->text_like('#pkg-license small', qr/\(not SPDX\)/)->text_like('#pkg-shortname', qr/\w+/) - ->text_like('#num-spec-files a', qr/2 files/)->text_like('#pkg-version', qr!7\.25!) - ->text_like('#pkg-summary', qr!Real-time web framework!)->text_like('#pkg-group', qr!Development/Libraries/Perl!) - ->text_like('#pkg-url a', qr!http://search\.cpan\.org/dist/Mojolicious/!)->text_like('#pkg-state', qr!new!) - ->element_exists('#pkg-review')->element_exists('#pkg-shortname')->element_exists('#pkg-review label[for=comment]') - ->element_exists('#pkg-review textarea[name=comment]')->element_exists('#correct')->element_exists('#acceptable') - ->element_exists('#unacceptable'); - - $t->text_like('#spec-files table tr:nth-of-type(2) th', qr/perl-Mojolicious\.spec/) - ->text_like('#spec-files table tr:nth-of-type(2) table tr td', qr/Licenses/) - ->text_like('#spec-files table tr:nth-of-type(2) table tr td:nth-of-type(2)', qr/Fake-Artistic/) - ->text_like('#spec-files table tr:nth-of-type(2) table tr:nth-of-type(3) td', qr/Version/) - ->text_like('#spec-files table tr:nth-of-type(2) table tr:nth-of-type(3) td:nth-of-type(2)', qr/7\.25/) - ->text_like('#spec-files table tr:nth-of-type(2) table tr:nth-of-type(4) td', qr/Summary/) - ->text_like('#spec-files table tr:nth-of-type(2) table tr:nth-of-type(4) td:nth-of-type(2)', - qr/Real-time web framework/) - ->text_like('#spec-files table tr:nth-of-type(2) table tr:nth-of-type(5) td', qr/Group/) - ->text_like('#spec-files table tr:nth-of-type(2) table tr:nth-of-type(5) td:nth-of-type(2)', - qr/Development\/Libraries\/Perl/)->text_like('#spec-files table tr th', qr/perl-Mojolicious-whatever\.spec/) - ->text_like('#spec-files table table tr td', qr/Licenses/) - ->text_like('#spec-files table tr td:nth-of-type(2)', qr/MIT, BSD, Artistic2/) - ->text_like('#spec-files table tr:nth-of-type(3) td', qr/Version/) - ->text_like('#spec-files table tr:nth-of-type(3) td:nth-of-type(2)', qr/1\.2\.3/) - ->text_like('#spec-files table tr:nth-of-type(4) td', qr/Summary/) - ->text_like('#spec-files table tr:nth-of-type(4) td:nth-of-type(2)', qr/Fake summary/) - ->text_like('#spec-files table table tr:nth-of-type(5) td', qr/Group/) - ->text_like('#spec-files table table tr:nth-of-type(5) td:nth-of-type(2)', qr/Fake group/); - - $t->text_like('#spec-errors p', qr/Package file errors/) - ->text_like('#spec-errors ul li', qr/Invalid SPDX license: Fake-Artistic/)->element_exists_not('#spec-warnings'); + $t->get_ok('/reviews/meta/1')->status_is(200)->json_like('/package_license/name', qr!Fake-Artistic!) + ->json_is('/package_license/spdx', undef)->json_like('/package_shortname', qr/\w+/)->json_has('/package_files/1') + ->json_like('/package_version', qr!7\.25!)->json_like('/package_summary', qr!Real-time web framework!) + ->json_like('/package_group', qr!Development/Libraries/Perl!) + ->json_like('/package_url', qr!http://search\.cpan\.org/dist/Mojolicious/!)->json_like('/state', qr!new!); + + $t->get_ok('/reviews/meta/1')->status_is(200)->json_like('/package_license/name', qr!Fake-Artistic!) + ->json_is('/package_license/spdx', undef)->json_like('/package_shortname', qr/\w+/)->json_has('/package_files/1') + ->json_like('/package_version', qr!7\.25!)->json_like('/package_summary', qr!Real-time web framework!) + ->json_like('/package_group', qr!Development/Libraries/Perl!) + ->json_like('/package_url', qr!http://search\.cpan\.org/dist/Mojolicious/!)->json_like('/state', qr!new!); + + $t->json_like('/package_files/1/file', qr/perl-Mojolicious\.spec/) + ->json_like('/package_files/1/licenses/0', qr/Fake-Artistic/)->json_like('/package_files/1/version', qr/7\.25/) + ->json_like('/package_files/1/summary', qr/Real-time web framework/) + ->json_like('/package_files/1/group', qr/Development\/Libraries\/Perl/) + ->json_like('/package_files/0/file', qr/perl-Mojolicious-whatever\.spec/) + ->json_is('/package_files/0/licenses', ['MIT', 'BSD', 'Artistic2']) + ->json_like('/package_files/0/version', qr/1\.2\.3/)->json_like('/package_files/0/summary', qr/Fake summary/) + ->json_like('/package_files/0/group', qr/Fake group/); + + $t->json_like('/errors/0', qr/Invalid SPDX license: Fake-Artistic/)->json_is('/warnings', []); $t->get_ok('/reviews/calc_report/1')->status_is(200)->element_exists('#license-chart')->element_exists('#emails') ->text_like('#emails tbody td', qr!coolo\@suse\.com!)->element_exists('#urls') @@ -167,13 +158,12 @@ subtest 'Manual review' => sub { $t->post_ok('/reviews/review_package/1' => form => {comment => 'Test review', acceptable => 'Good Enough'}) ->status_is(200)->text_like('#content a', qr!perl-Mojolicious!)->text_like('#content b', qr!acceptable!); - $t->get_ok('/reviews/details/1')->status_is(200)->text_like('#pkg-license', qr!Fake-Artistic!) - ->text_like('#pkg-version', qr!7\.25!)->text_like('#pkg-summary', qr!Real-time web framework!) - ->text_like('#pkg-group', qr!Development/Libraries/Perl!) - ->text_like('#pkg-url a', qr!http://search\.cpan\.org/dist/Mojolicious/!)->text_like('#pkg-state', qr!acceptable!) - ->element_exists('#pkg-review')->element_exists('#pkg-shortname')->element_exists('#pkg-review label[for=comment]') - ->element_exists('#pkg-review textarea[name=comment]')->element_exists('#correct')->element_exists('#acceptable') - ->element_exists('#unacceptable'); + $t->get_ok('/reviews/meta/1')->status_is(200)->json_like('/package_license/name', qr!Fake-Artistic!) + ->json_is('/package_license/spdx', undef)->json_like('/package_shortname', qr/\w+/)->json_has('/package_files/1') + ->json_like('/package_version', qr!7\.25!)->json_like('/package_summary', qr!Real-time web framework!) + ->json_like('/package_group', qr!Development/Libraries/Perl!) + ->json_like('/package_url', qr!http://search\.cpan\.org/dist/Mojolicious/!)->json_like('/state', qr!acceptable!) + ->json_like('/result', qr/Test review/); $t->get_ok('/reviews/calc_report/1')->status_is(200)->element_exists('#license-chart') ->element_exists('#unmatched-files')->text_is('#unmatched-count', '4') diff --git a/t/manual_review.t b/t/manual_review.t index 12623df938..dd6acd00a7 100644 --- a/t/manual_review.t +++ b/t/manual_review.t @@ -32,25 +32,18 @@ my $t = Test::Mojo->new(Cavil => $cavil_test->default_config); $cavil_test->mojo_fixtures($t->app); subtest 'Details after import (indexing in progress)' => sub { - $t->get_ok('/reviews/details/1')->status_is(200)->text_like('#pkg-license', qr!Artistic-2.0!) - ->text_like('#pkg-version', qr!7\.25!)->text_like('#pkg-summary', qr!Real-time web framework!) - ->text_like('#pkg-group', qr!Development/Libraries/Perl!) - ->text_like('#pkg-url a', qr!http://search\.cpan\.org/dist/Mojolicious/!)->text_like('#pkg-state', qr!new!) - ->element_exists_not('#pkg-review')->element_exists_not('#pkg-shortname') - ->element_exists_not('#pkg-review label[for=comment]')->element_exists_not('#pkg-review textarea[name=comment]') - ->element_exists_not('#correct')->element_exists_not('#acceptable')->element_exists_not('#unacceptable'); - - $t->text_like('#spec-files table tr th', qr/perl-Mojolicious\.spec/) - ->text_like('#spec-files table table tr td', qr/Licenses/) - ->text_like('#spec-files table table tr td:nth-of-type(2)', qr/Artistic-2.0/) - ->text_like('#spec-files table table tr:nth-of-type(3) td', qr/Version/) - ->text_like('#spec-files table table tr:nth-of-type(3) td:nth-of-type(2)', qr/7\.25/) - ->text_like('#spec-files table table tr:nth-of-type(4) td', qr/Summary/) - ->text_like('#spec-files table table tr:nth-of-type(4) td:nth-of-type(2)', qr/Real-time web framework/) - ->text_like('#spec-files table table tr:nth-of-type(5) td', qr/Group/) - ->text_like('#spec-files table table tr:nth-of-type(5) td:nth-of-type(2)', qr/Development\/Libraries\/Perl/); - - $t->element_exists_not('#spec-errors')->element_exists_not('#spec-warnings'); + $t->get_ok('/reviews/meta/1')->status_is(200)->json_like('/package_license/name', qr!Artistic-2.0!) + ->json_is('/package_license/spdx', 1)->json_like('/package_version', qr!7\.25!) + ->json_like('/package_summary', qr!Real-time web framework!) + ->json_like('/package_group', qr!Development/Libraries/Perl!) + ->json_like('/package_url', qr!http://search\.cpan\.org/dist/Mojolicious/!)->json_like('/state', qr!new!); + + $t->json_like('/package_files/0/file', qr/perl-Mojolicious\.spec/) + ->json_like('/package_files/0/licenses/0', qr/Artistic-2.0/)->json_like('/package_files/0/version', qr/7\.25/) + ->json_like('/package_files/0/summary', qr/Real-time web framework/) + ->json_like('/package_files/0/group', qr/Development\/Libraries\/Perl/); + + $t->json_is('/errors', [])->json_is('/warnings', []); $t->get_ok('/reviews/calc_report/1')->status_is(408)->content_like(qr/not indexed/); $t->get_ok('/reviews/fetch_source/1')->status_is(404); @@ -59,13 +52,12 @@ subtest 'Details after import (indexing in progress)' => sub { subtest 'Details after import (with login)' => sub { $t->get_ok('/login')->status_is(302)->header_is(Location => '/'); - $t->get_ok('/reviews/details/1')->status_is(200)->text_like('#pkg-license', qr!Artistic-2.0!) - ->text_like('#pkg-version', qr!7\.25!)->text_like('#pkg-summary', qr!Real-time web framework!) - ->text_like('#pkg-group', qr!Development/Libraries/Perl!) - ->text_like('#pkg-url a', qr!http://search\.cpan\.org/dist/Mojolicious/!)->text_like('#pkg-state', qr!new!) - ->element_exists('#pkg-review')->element_exists_not('#pkg-shortname') - ->element_exists('#pkg-review label[for=comment]')->element_exists('#pkg-review textarea[name=comment]') - ->element_exists('#correct')->element_exists('#acceptable')->element_exists('#unacceptable'); + $t->get_ok('/reviews/meta/1')->status_is(200)->json_like('/package_license/name', qr!Artistic-2.0!) + ->json_is('/package_license/spdx', 1)->json_like('/package_version', qr!7\.25!) + ->json_like('/package_summary', qr!Real-time web framework!) + ->json_like('/package_group', qr!Development/Libraries/Perl!) + ->json_like('/package_url', qr!http://search\.cpan\.org/dist/Mojolicious/!)->json_like('/state', qr!new!); + $t->get_ok('/reviews/calc_report/1')->status_is(408)->content_like(qr/not indexed/); $t->get_ok('/logout')->status_is(302)->header_is(Location => '/'); @@ -101,13 +93,11 @@ subtest 'Snippets after indexing' => sub { subtest 'Details after indexing' => sub { $t->get_ok('/login')->status_is(302)->header_is(Location => '/'); - $t->get_ok('/reviews/details/1')->status_is(200)->text_like('#pkg-license', qr!Artistic-2.0!) - ->text_like('#num-spec-files a', qr/1 file/)->text_like('#pkg-version', qr!7\.25!) - ->text_like('#pkg-summary', qr!Real-time web framework!)->text_like('#pkg-group', qr!Development/Libraries/Perl!) - ->text_like('#pkg-url a', qr!http://search\.cpan\.org/dist/Mojolicious/!)->text_like('#pkg-state', qr!new!) - ->element_exists('#pkg-review')->element_exists('#pkg-shortname')->element_exists('#pkg-review label[for=comment]') - ->element_exists('#pkg-review textarea[name=comment]')->element_exists('#correct')->element_exists('#acceptable') - ->element_exists('#unacceptable'); + $t->get_ok('/reviews/meta/1')->status_is(200)->json_like('/package_license/name', qr!Artistic-2.0!) + ->json_is('/package_license/spdx', 1)->json_like('/package_version', qr!7\.25!) + ->json_like('/package_summary', qr!Real-time web framework!) + ->json_like('/package_group', qr!Development/Libraries/Perl!) + ->json_like('/package_url', qr!http://search\.cpan\.org/dist/Mojolicious/!)->json_like('/state', qr!new!); $t->get_ok('/reviews/calc_report/1')->status_is(200)->element_exists('#license-chart')->element_exists('#emails') ->text_like('#emails tbody td', qr!coolo\@suse\.com!)->element_exists('#urls') @@ -202,13 +192,11 @@ subtest 'Snippets after reindexing' => sub { subtest 'Details after reindexing' => sub { $t->get_ok('/login')->status_is(302)->header_is(Location => '/'); - $t->get_ok('/reviews/details/1')->status_is(200)->text_like('#pkg-license', qr!Artistic-2.0!) - ->text_like('#pkg-version', qr!7\.25!)->text_like('#pkg-summary', qr!Real-time web framework!) - ->text_like('#pkg-group', qr!Development/Libraries/Perl!) - ->text_like('#pkg-url a', qr!http://search\.cpan\.org/dist/Mojolicious/!)->text_like('#pkg-state', qr!new!) - ->element_exists('#pkg-review')->element_exists('#pkg-shortname')->element_exists('#pkg-review label[for=comment]') - ->element_exists('#pkg-review textarea[name=comment]')->element_exists('#correct')->element_exists('#acceptable') - ->element_exists('#unacceptable'); + $t->get_ok('/reviews/meta/1')->status_is(200)->json_has('/package_shortname') + ->json_like('/package_license/name', qr!Artistic-2.0!)->json_is('/package_license/spdx', 1) + ->json_like('/package_version', qr!7\.25!)->json_like('/package_summary', qr!Real-time web framework!) + ->json_like('/package_group', qr!Development/Libraries/Perl!) + ->json_like('/package_url', qr!http://search\.cpan\.org/dist/Mojolicious/!)->json_like('/state', qr!new!); $t->get_ok('/reviews/calc_report/1')->header_like(Vary => qr/Accept-Encoding/)->status_is(200) ->element_exists('#license-chart')->element_exists('#unmatched-files')->text_is('#unmatched-count', '4') @@ -235,13 +223,12 @@ subtest 'Manual review' => sub { $t->post_ok('/reviews/review_package/1' => form => {comment => 'Test review', acceptable => 'Good Enough'}) ->status_is(200)->text_like('#content a', qr!perl-Mojolicious!)->text_like('#content b', qr!acceptable!); - $t->get_ok('/reviews/details/1')->status_is(200)->text_like('#pkg-license', qr!Artistic-2.0!) - ->text_like('#pkg-version', qr!7\.25!)->text_like('#pkg-summary', qr!Real-time web framework!) - ->text_like('#pkg-group', qr!Development/Libraries/Perl!) - ->text_like('#pkg-url a', qr!http://search\.cpan\.org/dist/Mojolicious/!)->text_like('#pkg-state', qr!acceptable!) - ->element_exists('#pkg-review')->element_exists('#pkg-shortname')->element_exists('#pkg-review label[for=comment]') - ->element_exists('#pkg-review textarea[name=comment]')->element_exists('#correct')->element_exists('#acceptable') - ->element_exists('#unacceptable'); + $t->get_ok('/reviews/meta/1')->status_is(200)->json_has('/package_shortname') + ->json_like('/package_license/name', qr!Artistic-2.0!)->json_is('/package_license/spdx', 1) + ->json_like('/package_version', qr!7\.25!)->json_like('/package_summary', qr!Real-time web framework!) + ->json_like('/package_group', qr!Development/Libraries/Perl!) + ->json_like('/package_url', qr!http://search\.cpan\.org/dist/Mojolicious/!)->json_like('/state', qr!acceptable!) + ->json_like('/result', qr/Test review/); $t->get_ok('/reviews/calc_report/1')->status_is(200)->element_exists('#license-chart') ->element_exists('#unmatched-files')->text_is('#unmatched-count', '4') diff --git a/templates/reviewer/details.html.ep b/templates/reviewer/details.html.ep index 05f9ab1ae7..930ca23a5b 100644 --- a/templates/reviewer/details.html.ep +++ b/templates/reviewer/details.html.ep @@ -1,26 +1,13 @@ % layout 'default'; % title "Report for $package->{name}"; -
- % my @sub = @{$spec->{sub} // []}; - % if (grep { ($_->{type} // '') eq 'spec' } @sub) { - - % } - % if (grep { ($_->{type} // '') eq 'kiwi' } @sub) { - - % } - % if (grep { ($_->{type} // '') eq 'dockerfile' } @sub) { - - % } - % if (grep { ($_->{type} // '') eq 'helm' } @sub) { - - % } -
+
-

- <%= link_to $package->{name} => - url_for('search')->query(q => $package->{name}), target => '_blank' %> -

+% content_for 'ready_function' => begin + % my $has_manager_role = current_user_has_role('manager') ? 'true' : 'false'; + % my $has_admin_role = current_user_has_role('admin') ? 'true' : 'false'; + cavil.setupReportMetadata(<%= $id %>, <%= $has_manager_role %> ,<%= $has_admin_role %>); +% end % my $raw_license = $spec->{main}{license}; % my $license = lic($raw_license)->to_string; @@ -30,378 +17,6 @@ cavil.fromNow(); cavil.backToTop(); % end - - - % if ($display_license) { - - - - - - % } - - % if ($spec->{sub} && @{$spec->{sub}}) { - - - - - - % } - - % if (my $link = $package->{external_link}) { - - - - - - % } - - % if (@$requests) { - - - - - - % } - - % if (@$actions) { - - - - - - % } - - % if (@$products) { - - - - - - % } - - % if (my $version = $spec->{main}{version}) { - - - - - - % } - - % if (my $summary = $spec->{main}{summary}) { - - - - - - % } - - % if (my $group = $spec->{main}{group}) { - - - - - - % } - - % if (my $url = $spec->{main}{url}) { - - - - - - % } - - - - - - - - % if (my $report = $package->{checksum}) { - % my ($shortname) = $report =~ /:(\w+)$/; - - - - - - % } - - - - - - - - % if (my $reviewed = $package->{reviewed_epoch}) { - - - - - - % } - - % if (my $login = $package->{login}) { - - - - - - % } - - - - - - - - % if (@$history) { - - - - - - % } - -
- - License: - <%= $display_license %> - % unless ($license) { - (not SPDX) - % } -
- - Package Files: - % if (my $num = @{$spec->{sub}}) { - <%= link_to $num == 1 ? '1 file' : "$num files" => "#spec-files", 'data-toggle' => 'collapse' %> - % } -
- - External Link:<%= format_link($package->{external_link}) %>
- - Requests:<%== join(', ', map { format_link($_) } @$requests) %>
- - Actions: - % if (my $num = @$actions) { - <%= link_to - $num == 1 ? '1 related review' : "$num related reviews" - => "#actions", 'data-toggle' => 'collapse' %> - % } -
- - Products:<%== join ', ', map { link_to $_ => 'product_show', {name => $_} } @$products %>
- - Version:<%= $version %>
- - Summary:<%= $summary %>
- - Group:<%= $group %>
- - URL:<%= link_to $url => $url => (target => '_blank') %>
- - SPDX Report: - - <%= $has_spdx_report ? 'available' : 'not yet generated' %> - -
- - Shortname:<%= $shortname %>
- - Created:<%= $package->{created_epoch} %>
- - Reviewed:<%= $reviewed %>
- - Reviewing User:<%= $login %>
- - State:<%= $package->{state} %>
- - History: - % if (my $num = @$history) { - <%= link_to - $num == 1 ? '1 other review' : "$num other reviews" => "#history", - 'data-toggle' => 'collapse' %> - % } -
- -% if ($spec->{sub} && @{$spec->{sub}}) { -
-
- - - % for my $sub (@{$spec->{sub}}) { - - - - % } - -
- - - - - % if (@{$sub->{licenses}}) { - - - - - % } - % if (my $version = $sub->{version}) { - - - - - % } - % if (my $summary = $sub->{summary}) { - - - - - % } - % if (my $group = $sub->{group}) { - - - - - % } -
- <%= $sub->{file} %> -
Licenses:<%= c(@{$sub->{licenses}})->uniq->join(', ') %>
Version:<%= $version %>
Summary:<%= $summary %>
Group:<%= $group %>
-
-
-
-% } - -% if (@$actions) { -
- - - % for my $result (@$actions) { - - - - - - - - % } - -
<%= $result->{name} %><%= $result->{result} || '' %><%= $result->{state} %><%= $result->{login} || '' %> - % my $url = url_for package_details => {id => $result->{id}}; - <%= link_to $result->{created_epoch} => $url, - target => '_blank', class => 'from-now' %> -
-
-% } - -% if (@$history) { -
- - - % for my $result (@$history) { - - - - - - - - % } - -
<%= format_link($result->{external_link}) %><%= $result->{result} || '' %><%= $result->{state} %><%= $result->{login} || '' %> - % my $url = url_for package_details => {id => $result->{id}}; - <%= link_to $result->{created_epoch} => $url, - target => '_blank', class => 'from-now' %> -
-
-% } - -% if (@{$spec->{errors} // []}) { -
-

Package file errors:

-
    - % for my $l (@{$spec->{errors}}) { - %= t li => $l - % } -
-
-% } -% if (@{$spec->{warnings} // []}) { -
-

Package file warnings:

-
    - % for my $l (@{$spec->{warnings}}) { - %= t li => $l - % } -
-
-% } - -% if (current_user_has_role 'admin') { -
- %= form_for review_package => (class => 'container', id => 'pkg-review') => begin -
- - -
- %= submit_button 'Checked', class => 'btn btn-success', id => 'correct', name => 'correct' - %= submit_button 'Good Enough', class => 'btn btn-warning', id => 'acceptable', name => 'acceptable' - %= submit_button 'Unacceptable', class => 'btn btn-danger', id => 'unacceptable', name => 'unacceptable' - % end -
-% } -% elsif (current_user_has_role 'manager') { -
- %= form_for fasttrack_package => (class => 'container') => begin -
- - -
- %= submit_button 'Accept without legal review', class => 'btn btn-warning', id => 'acceptable', name => 'acceptable' - % end -
-% } -% elsif (my $comment = $package->{result}) { -
-
-
- - -
-
-
-% } - -% my %docs; -% my %lics; -% for my $sub (@{$spec->{sub} // []}) { - % for my $line (@{$sub->{'%doc'}}) { - % for my $file (split(/ /, $line)) { - % $docs{$file} = 1; - % } - % } - % for my $line (@{$sub->{'%license'}}) { - % for my $file (split(/ /, $line)) { - % $lics{$file} = 1; - % } - % } -% } -% if (%docs || %lics) { -
- % if (%docs) { -

- Files copied as %doc: - %= join ' ', sort keys %docs -

- % } - % if (%lics) { -

- Files copied as %license: - %= join ' ', sort keys %lics -

- % } -
-% }

Licenses