diff options
author | Michael Schroeder <mls@suse.de> | 2018-10-11 13:32:24 +0200 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2018-10-11 13:32:24 +0200 |
commit | 66021c8a26525a120f1b26557543a1858f2f97b2 (patch) | |
tree | e68fa9c00674f6fe9f6fb498d6bde7042cf8b3c0 /Build | |
parent | ab523b2ddf01577afa837490f325ad044b7fe6e0 (diff) |
Add Build::SimpleJSON and use it to write containerinfo files
Diffstat (limited to 'Build')
-rw-r--r-- | Build/Docker.pm | 38 | ||||
-rw-r--r-- | Build/Kiwi.pm | 31 | ||||
-rw-r--r-- | Build/SimpleJSON.pm | 102 |
3 files changed, 139 insertions, 32 deletions
diff --git a/Build/Docker.pm b/Build/Docker.pm index 7a9cc4f..9e5a56c 100644 --- a/Build/Docker.pm +++ b/Build/Docker.pm @@ -20,7 +20,8 @@ package Build::Docker; -use Build::SimpleXML; +use Build::SimpleXML; # to parse the annotation +use Build::SimpleJSON; use strict; @@ -44,9 +45,10 @@ sub quote { } sub addrepo { - my ($ret, $url) = @_; + my ($ret, $url, $prio) = @_; - unshift @{$ret->{'repo_urls'}}, $url; + unshift @{$ret->{'imagerepos'}}, { 'url' => $url }; + $ret->{'imagerepos'}->[0]->{'priority'} = $prio if defined $prio; if ($Build::Kiwi::urlmapper) { my $prp = $Build::Kiwi::urlmapper->($url); if (!$prp) { @@ -55,15 +57,17 @@ sub addrepo { } my ($projid, $repoid) = split('/', $prp, 2); unshift @{$ret->{'path'}}, {'project' => $projid, 'repository' => $repoid}; - return; + $ret->{'path'}->[0]->{'priority'} = $prio if defined $prio; + return 1; } else { # this is just for testing purposes... $url =~ s/^\/+$//; $url =~ s/:\//:/g; my @url = split('/', $url); unshift @{$ret->{'path'}}, {'project' => $url[-2], 'repository' => $url[-1]} if @url >= 2; + $ret->{'path'}->[0]->{'priority'} = $prio if defined $prio; + return 1; } - return 1; } sub cmd_zypper { @@ -142,7 +146,7 @@ sub parse { 'name' => 'docker', 'deps' => [], 'path' => [], - 'repo_urls' => [], + 'imagerepos' => [], }; while (@lines) { @@ -222,8 +226,7 @@ sub showcontainerinfo { for (@tags) { $_ .= ':latest' unless /:[^:\/]+$/; } - @tags = map {"\"$_\""} @tags; - my @repos = map {"{ \"url\": \"$_\" }"} @{$d->{'repo_urls'} || []}; + my @repos = @{$d->{'imagerepos'} || []}; if ($annotationfile) { my $annotation = slurp($annotationfile); $annotation = Build::SimpleXML::parse($annotation) if $annotation; @@ -233,17 +236,20 @@ sub showcontainerinfo { $annorepos = undef unless $annorepos && ref($annorepos) eq 'ARRAY'; for my $annorepo (@{$annorepos || []}) { next unless $annorepo && ref($annorepo) eq 'HASH' && $annorepo->{'url'}; - push @repos, "{ \"url\": \"$annorepo->{'url'}\" }"; + push @repos, { 'url' => $annorepo->{'url'}, '_type' => {'priority' => 'number'} }; + $repos[-1]->{'priority'} = $annorepo->{'priority'} if defined $annorepo->{'priority'}; } } my $buildtime = time(); - print "{\n"; - print " \"tags\": [ ".join(', ', @tags)." ]"; - print ",\n \"repos\": [ ".join(', ', @repos)." ]" if @repos; - print ",\n \"file\": \"$image\"" if defined $image; - print ",\n \"disturl\": \"$disturl\"" if defined $disturl; - print ",\n \"buildtime\": $buildtime"; - print "\n}\n"; + my $containerinfo = { + 'buildtime' => $buildtime, + '_type' => {'buildtime' => 'number'}, + }; + $containerinfo->{'tags'} = \@tags if @tags; + $containerinfo->{'repos'} = \@repos if @repos; + $containerinfo->{'file'} = $image if defined $image; + $containerinfo->{'disturl'} = $disturl if defined $disturl; + print Build::SimpleJSON::unparse($containerinfo)."\n"; } sub showtags { diff --git a/Build/Kiwi.pm b/Build/Kiwi.pm index 2ac68af..9a452f3 100644 --- a/Build/Kiwi.pm +++ b/Build/Kiwi.pm @@ -22,6 +22,7 @@ package Build::Kiwi; use strict; use Build::SimpleXML; +use Build::SimpleJSON; our $bootcallback; our $urlmapper; @@ -537,26 +538,24 @@ sub showcontainerinfo { my $d = parse($cf, $fn); die("$d->{'error'}\n") if $d->{'error'}; $image =~ s/.*\/// if defined $image; - my @tags = map {"\"$_\""} @{$d->{'container_tags'} || []}; my @repos; for my $repo (@{$d->{'imagerepos'} || []}) { - if (defined $repo->{'priority'}) { - push @repos, "{ \"url\": \"$repo->{'url'}\", \"priority\": $repo->{'priority'} }"; - } else { - push @repos, "{ \"url\": \"$repo->{'url'}\" }"; - } + push @repos, { 'url' => $repo->{'url'}, '_type' => {'priority' => 'number'} }; + $repos[-1]->{'priority'} = $repo->{'priority'} if defined $repo->{'priority'}; } my $buildtime = time(); - print "{\n"; - print " \"name\": \"$d->{'name'}\""; - print ",\n \"version\": \"$d->{'version'}\"" if defined $d->{'version'}; - print ",\n \"release\": \"$release\"" if defined $release; - print ",\n \"tags\": [ ".join(', ', @tags)." ]" if @tags; - print ",\n \"repos\": [ ".join(', ', @repos)." ]" if @repos; - print ",\n \"file\": \"$image\"" if defined $image; - print ",\n \"disturl\": \"$disturl\"" if defined $disturl; - print ",\n \"buildtime\": $buildtime"; - print "\n}\n"; + my $containerinfo = { + 'name' => $d->{'name'}, + 'buildtime' => $buildtime, + '_type' => {'buildtime' => 'number'}, + }; + $containerinfo->{'version'} = $d->{'version'} if defined $d->{'version'}; + $containerinfo->{'release'} = $release if defined $d->{'version'}; + $containerinfo->{'tags'} = $d->{'container_tags'} if @{$d->{'container_tags'} || []}; + $containerinfo->{'repos'} = \@repos if @repos; + $containerinfo->{'file'} = $image if defined $image; + $containerinfo->{'disturl'} = $disturl if defined $disturl; + print Build::SimpleJSON::unparse($containerinfo)."\n"; } # not implemented yet. diff --git a/Build/SimpleJSON.pm b/Build/SimpleJSON.pm new file mode 100644 index 0000000..7e20ce6 --- /dev/null +++ b/Build/SimpleJSON.pm @@ -0,0 +1,102 @@ +################################################################ +# +# Copyright (c) 2018 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +package Build::SimpleJSON; + +use strict; + +sub unparse_keys { + my ($d) = @_; + my @k = grep {$_ ne '_start' && $_ ne '_end' && $_ ne '_order' && $_ ne '_type'} sort keys %$d; + return @k unless $d->{'_order'}; + my %k = map {$_ => 1} @k; + my @ko; + for (@{$d->{'_order'}}) { + push @ko, $_ if delete $k{$_}; + } + return (@ko, grep {$k{$_}} @k); +} + +my %specialescapes = ( + '"' => '\\"', + '\\' => '\\\\', + '/' => '\\/', + "\b" => '\\b', + "\f" => '\\f', + "\n" => '\\n', + "\r" => '\\r', + "\t" => '\\t', +); + +sub unparse_string { + my ($d) = @_; + $d =~ s/([\"\\\000-\037])/$specialescapes{$1} || sprintf('\\u%04d', ord($1))/ge; + return "\"$d\""; +} + +sub unparse_bool { + my ($d) = @_; + return $d ? 'true' : 'false'; +} + +sub unparse_number { + my ($d) = @_; + return sprintf("%.f", $d) if $d == int($d); + return sprintf("%g", $d); +} + +sub unparse { + my ($d, %opts) = @_; + + my $r = ''; + if (ref($d) eq 'ARRAY') { + return '[]' unless @$d; + my $indent = $opts{'ugly'} ? '' : $opts{'indent'} || ''; + my $nl = $opts{'ugly'} ? '' : "\n"; + my $sp = $opts{'ugly'} ? '' : " "; + my $first = 0; + for my $dd (@$d) { + $r .= ",$nl" if $first++; + $r .= "$indent$sp$sp$sp".unparse($dd, %opts, 'indent' => " $indent"); + } + return "\[$nl$r$nl$indent\]"; + } + if (ref($d) eq 'HASH') { + my @k = unparse_keys($d); + return '{}' unless @k; + my $indent = $opts{'ugly'} ? '' : $opts{'indent'} || ''; + my $nl = $opts{'ugly'} ? '' : "\n"; + my $sp = $opts{'ugly'} ? '' : " "; + my $first = 0; + for my $k (@k) { + $r .= ",$nl" if $first++; + my $dd = $d->{$k}; + $r .= "$indent$sp$sp$sp".unparse_string($k)."$sp:$sp".unparse($dd, %opts, 'indent' => " $indent", '_type' => ($d->{'_type'} || {})->{$k}); + } + return "\{$nl$r$nl$indent\}"; + } + return 'null' unless defined $d; + my $type = $opts{'_type'} || ''; + return unparse_bool($d) if $type eq 'bool'; + return unparse_number($d) if $type eq 'number'; + return unparse_string($d); +} + +1; |