diff options
-rwxr-xr-x | Master/texmf-dist/scripts/texlive/tlmgr.pl | 12 | ||||
-rw-r--r-- | Master/tlpkg/TeXLive/TLPDB.pm | 77 | ||||
-rw-r--r-- | Master/tlpkg/TeXLive/TLPOBJ.pm | 20 | ||||
-rw-r--r-- | Master/tlpkg/doc/JSON-formats.txt | 116 |
4 files changed, 206 insertions, 19 deletions
diff --git a/Master/texmf-dist/scripts/texlive/tlmgr.pl b/Master/texmf-dist/scripts/texlive/tlmgr.pl index e906af35ee6..763dc23f99e 100755 --- a/Master/texmf-dist/scripts/texlive/tlmgr.pl +++ b/Master/texmf-dist/scripts/texlive/tlmgr.pl @@ -1419,7 +1419,7 @@ sub action_info { if ($^O =~ /^MSWin/i) { # that should not happen, we are shipping Tk!! require Win32; - my $msg = "Cannot load JSON:PP, that should not happen as we ship it!\n(Error message: $@)\n"; + my $msg = "Cannot load JSON, that should not happen as we ship it!\n(Error message: $@)\n"; Win32::MsgBox($msg, 1|Win32::MB_ICONSTOP(), "Warning"); } else { printf STDERR " @@ -3643,7 +3643,9 @@ sub show_one_package_json { #return($F_WARNING); return($F_OK); } - my $tlp = ($is_available ? $remtlp : $loctlp); + # prefer local TLPs as they have RELOC replaced by proper paths + my $tlp = ($is_installed ? $loctlp : $remtlp); + #my $tlp = ($is_available ? $remtlp : $loctlp); # add available, installed, lrev, rrev fields and remove revision field my $str = $tlp->as_json(available => ($is_available ? $JSON::true : $JSON::false), installed => ($is_installed ? $JSON::true : $JSON::false), @@ -7476,7 +7478,8 @@ Dump the remote TLPDB. =item B<--json> Instead of dumping the actual content, the database is dumped as -JSON. +JSON. For the format of JSON output see C<tlpkg/doc/JSON-formats.txt>, +format definition C<TLPDB>. =back @@ -7669,7 +7672,8 @@ the name of all dependencies separated by C<:>. In case the only value passed to C<--data> is C<json>, the output is a JSON encoded array where each array element is the JSON representation of -the internal object. +a single C<TLPOBJ> but with additional information. For details see +C<tlpkg/doc/JSON-formats.txt>, format definition: C<TLPOBJINFO>. =back diff --git a/Master/tlpkg/TeXLive/TLPDB.pm b/Master/tlpkg/TeXLive/TLPDB.pm index cff1cfad2b7..9176a04e715 100644 --- a/Master/tlpkg/TeXLive/TLPDB.pm +++ b/Master/tlpkg/TeXLive/TLPDB.pm @@ -479,28 +479,77 @@ the tag of the sub-database, and C<tlpdb> giving the JSON of the database. sub as_json { my $self = shift; - my $ret; + require JSON; + my $ret = "{"; if ($self->is_virtual) { - $ret = "[\n"; my $firsttlpdb = 1; for my $k (keys %{$self->{'tlpdbs'}}) { $ret .= ",\n" if (!$firsttlpdb); - $ret .= "{ \"tag\" : \"$k\", \"tlpdb\" : "; + $ret .= "\"$k\":"; $firsttlpdb = 0; - $ret .= $self->{'tlpdbs'}{$k}->as_json; - $ret .= " }"; + $ret .= $self->{'tlpdbs'}{$k}->_as_json; } - $ret .= "\n]"; } else { - $ret = "[\n"; - my $first = 1; - foreach (keys %{$self->{'tlps'}}) { - $ret .= ",\n" if (!$first); - $first = 0; - $ret .= $self->{'tlps'}{$_}->as_json; - } - $ret .= "\n]"; + $ret .= "\"main\":"; + $ret .= $self->_as_json; } + $ret .= "}\n"; + return($ret); +} + +sub _as_json { + my $self = shift; + die("calling _as_json on virtual is not supported!") if ($self->is_virtual); + my $ret = "{"; + # options + $ret .= '"options":'; + my $opts = $self->options; + for my $k (keys %TeXLive::TLConfig::TLPDBOptions) { + if ($TeXLive::TLConfig::TLPDBOptions{$k}[0] =~ m/^n/) { + $opts->{$k} += 0 if (exists($opts->{$k})); + } elsif ($TeXLive::TLConfig::TLPDBOptions{$k}[0] eq "b") { + $opts->{$k} = ($opts->{$k} ? $JSON::true : $JSON::false) if (exists($opts->{$k})); + } elsif ($k eq "location") { + if (exists($opts->{$k})) { + my %foo = TeXLive::TLUtils::repository_to_array($opts->{$k}); + delete($opts->{$k}); + for my $u (keys %foo) { + $opts->{$k}{$u} = $foo{$u}; + } + } + } + # the last else is plain strings, nothing to do + } + $ret .= JSON::encode_json($opts); + $ret .= ',"settings":'; + my $sets = $self->settings; + for my $k (keys %TeXLive::TLConfig::TLPDBSettings) { + if ($TeXLive::TLConfig::TLPDBSettings{$k} eq "b") { + $sets->{$k} = ($sets->{$k} ? $JSON::true : $JSON::false) if (exists($sets->{$k})); + } elsif ($TeXLive::TLConfig::TLPDBSettings{$k} eq "available_architectures") { + delete($sets->{$k}); + @{$sets->{$k}} = $self->available_architectures; + } + # else are strings + } + $ret .= JSON::encode_json($sets); + $ret .= ',"configs":'; + my %cfgs; + $cfgs{'container_split_src_files'} = ($self->config_src_container ? $JSON::true : $JSON::false); + $cfgs{'container_split_doc_files'} = ($self->config_doc_container ? $JSON::true : $JSON::false); + $cfgs{'container_format'} = $self->config_container_format; + $cfgs{'release'} = $self->config_release; + $cfgs{'minrelease'} = $self->config_minrelease; + $ret .= JSON::encode_json(\%cfgs); + $ret .= ',"tlpkgs": ['; + my $first = 1; + foreach (keys %{$self->{'tlps'}}) { + $ret .= ",\n" if (!$first); + $first = 0; + $ret .= $self->{'tlps'}{$_}->as_json; + } + $ret .= "]}"; + return($ret); } =pod diff --git a/Master/tlpkg/TeXLive/TLPOBJ.pm b/Master/tlpkg/TeXLive/TLPOBJ.pm index 6ff4908c0f8..0ca7ebb6d19 100644 --- a/Master/tlpkg/TeXLive/TLPOBJ.pm +++ b/Master/tlpkg/TeXLive/TLPOBJ.pm @@ -450,7 +450,25 @@ sub as_json { $foo{'relocated'} = $JSON::false; } } - my $utf8_encoded_json_text = JSON::encode_json(\%foo); # $json->encode(\%foo); + # adjust the docfiles entry to the specification in JSON-formats + my @docf = $self->docfiles; + my $dfd = $self->docfiledata; + my @newdocf; + for my $f ($self->docfiles) { + my %newd; + $newd{'file'} = $f; + if (defined($dfd->{$f})) { + # TODO should we check that there are actually only "details" + # and "language" as key? + for my $k (keys %{$dfd->{$f}}) { + $newd{$k} = $dfd->{$f}->{$k}; + } + } + push @newdocf, \%newd; + } + $foo{'docfiles'} = [ @newdocf ]; + delete($foo{'docfiledata'}); + my $utf8_encoded_json_text = JSON::encode_json(\%foo); return $utf8_encoded_json_text; } diff --git a/Master/tlpkg/doc/JSON-formats.txt b/Master/tlpkg/doc/JSON-formats.txt new file mode 100644 index 00000000000..6f8a8bf8967 --- /dev/null +++ b/Master/tlpkg/doc/JSON-formats.txt @@ -0,0 +1,116 @@ +JSON formats for the various outputs of tlmgr +============================================= + +Guaranteed to be present fields are marked with a * + +TLPOBJ +------ +JSON object with key/values according to the underlying structure with a few +exception (docfiles and docfiledata are merged). Details: + +* String type: + *name, shortdesc, longdesc, *category, catalogue, containerchecksum, + srccontainerchecksum, doccontainerchecksum + Example: "name": "12many" + +* Number type: + *revision, runsize, docsize, srcsize, containersize, srccontainersize, doccontainersize + Example: "revision": 12345 + +* Boolean type: + available, installed, relocated + Example: "relocated": false + +* Array type (with the sub-type in parenthesis): + - of String type: runfiles, srcfiles, executes, depends, postactions + Example: "runfiles": [ "texmf-dist/...", "texmf-dist/...file2" ] + - of Object type: + . docfiles: keys: *file, language, details (all Strings) + Example: + [ { "file": "docfile1", "lang": "en" }, { "file": "docfile2", "detail": "readme file" } ] + +* Object type: + - binfiles: keys are architecture names, values are arrays of strings (list of binfiles) + Example: { "x86_64-linux": [ "binfile1", "binfile2", ... ], "win32": [ "binfile3" ] } + - binsize: keys are architecture names, values are numbers + Example: { "x86_64-linux": 1233, "win32": 333 } + - cataloguedata: keys are topics, version, license, ctan, date, values are all strings + Example: { "topics": "graphic", "version": "1.23" } + + +Note: A minimal TLPOBJ might look like +{ + "name": "minimal", + "category": "Package", + "revision": 12345 +} + + + +TLPOBJINFO +---------- +This JSON format is dumped on tlmgr info --data json and is slightly different +format compared to TLPOBJ above: + +Removed fields: revision +Added fields: +- Number type: lrev, rrev -- local and remote revision of the package +- Boolean type: available (available at repository), installed + + +TLPDBSINGLE +----------- +JSON object with the following fields: +* Object type: + - options: keys are the tlmgr names of %TLConfig::TLPDBOptions, that is + . Number type: autobackup, fileassocs + . Boolean type: formats, desktop_integration, generate_updmap, docfiles, + srcfiles, postcode, w32_multi_user + . String type: backupdir, location, sys_bin, sys_info, sys_man + . Object type: repository: keys are tags, values are Strings + if there is only one location then the tag is "main" + Example: + "options": { + "autobackup": 2, + "formats": false, + "postcode": true, + "backupdir": "/backup/tl", + "repository": { + "main": "http://mirror.ctan.org/systems/texlive/tlnet", + "tlcontrib": "..." + } + } + + - settings: keys are the names of %TLConfig::TLPDBSettings, that is + . Boolean type: usertree + . String type: platform + . Array type: available_architectures (Strings) + + - configs: keys are the names of %TLConfig::TLPDBConfigs, that is + . Boolean type: container_split_src_files, container_split_doc_files + . String type: container_format, minrelease, release + +* Array type: + - tlpkgs: JSON array of TLPOBJs in JSON format + + +TLPDB +----- +This format is used when dumping tlpdb, local or remote +JSON object with the following fields: +keys are tags, values are tlpdb in TLPDBSINGLE format +Example: +{ + "main": { + "options": {...}, + "tlpkgs": [...] + }, + "tlcontrib": { + "option": {...}, + "tlpkgs": [...] + } +} + + +TODO + UPDATE JSON format |