summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2017-10-27 05:26:10 +0000
committerNorbert Preining <preining@logic.at>2017-10-27 05:26:10 +0000
commit0bd7e97c405a4efd80b8e304486b4d35825c277c (patch)
treebeeee0027651ed1eeac28a6cdd0410d5d7ac4451
parentbd41846f4f09f09f3bcc3efa0f49795a63461035 (diff)
update JSON format, add documentation on formats
git-svn-id: svn://tug.org/texlive/trunk@45620 c570f23f-e606-0410-a88d-b1316a301751
-rwxr-xr-xMaster/texmf-dist/scripts/texlive/tlmgr.pl12
-rw-r--r--Master/tlpkg/TeXLive/TLPDB.pm77
-rw-r--r--Master/tlpkg/TeXLive/TLPOBJ.pm20
-rw-r--r--Master/tlpkg/doc/JSON-formats.txt116
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