summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2018-10-11 13:32:24 +0200
committerMichael Schroeder <mls@suse.de>2018-10-11 13:32:24 +0200
commit66021c8a26525a120f1b26557543a1858f2f97b2 (patch)
treee68fa9c00674f6fe9f6fb498d6bde7042cf8b3c0 /Build
parentab523b2ddf01577afa837490f325ad044b7fe6e0 (diff)
Add Build::SimpleJSON and use it to write containerinfo files
Diffstat (limited to 'Build')
-rw-r--r--Build/Docker.pm38
-rw-r--r--Build/Kiwi.pm31
-rw-r--r--Build/SimpleJSON.pm102
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;