Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Sep 2018 11:44:15 +0100
From:      Matt Churchyard <churchers@gmail.com>
To:        phil@juniper.net
Cc:        freebsd-hackers@freebsd.org, sjg@juniper.net
Subject:   Re: Getting valid JSON output with xo(1)
Message-ID:  <CANV9Nzm9MKkUy%2B0bH_bQpOiey1MKk7q0_z2cauF4L185ujPQYQ@mail.gmail.com>
In-Reply-To: <201809110129.w8B1TG1Z022255@idle.juniper.net>
References:  <CANV9Nz=3aOd5RM9KyTfz-1_%2BEnffKEOVQbYZxJY=i9_x0gorpA@mail.gmail.com> <201809110129.w8B1TG1Z022255@idle.juniper.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Phil,

Thanks for the detailed response.

The part about HTML makes perfect sense. Each outer div is a "line", so
without the "\n", you may well want to create further output on the same
line by making additional calls. (Assuming of course that you can use the
--not-first option to stop it creating another "line" div)

As you mention, the fact that xo(1) is designed to be called multiple times
in order to build up the output from fragments makes some of this stuff
awkward. Thanks for pointing out the --not-first option.

I think the sample from #61 looks fairly reasonable. Not that I want to
create you guys extra work..., I've no doubt your primary focus is libxo
itself which already works fine. Just seems that the xo command line
utility is quite hampered if it can't create lists (in JSON at least). At
the moment I'm getting around it fairly simply by using something like the
following, (the tr calls fortunately only have an effect on JSON output.),
which works, but is a lot of jumping through hoops just to get valid JSON.

xo -pJ --open machines | tr '{' '['
(if JSON & not first) echo ","
(if JSON) echo "{"
(if JSON) xo -pJ "{:key1}{:key2}{:key3}" data1 data2 data3
(if not JSON) xo -pJ --wrap machine "{:key1}{:key2}{:key3}" data1 data2
data3
(if JSON) echo "}"
xo -pJ --close machines | tr '}' ']'

Regards,
Matt

On Tue, Sep 11, 2018 at 2:28 AM Phil Shafer <phil@juniper.net> wrote:

> Matt Churchyard writes:
> >Sorry if this is the wrong list, I wasn't sure which was the most
> >appropriate.
>
> Best path for xo-related bugs is https://github.com/Juniper/libxo/issues
> Email directly to phil@ is also reasonable.
>
> >If I choose HTML output I get the following invalid output which is
> missing
> >closing </div> tags.
> >
> ><div class="line">
> >  <div class="data" data-tag="name">test1</div>
> >  <div class="text">,</div>
> >  <div class="data" data-tag="memory">2GB</div>
> ><div class="line">
> >  <div class="data" data-tag="name">test2</div>
> >  <div class="text">,</div>
> >  <div class="data" data-tag="memory">4GB</div>
> >
> >This can be fixed by adding "\n" to the end of the format lines, which may
> >be required, but it seems strange that I can so easily generate broken
> >output.
>
> Yes, without a trailing newline, libxo can't declare the output
> line "over", so it doesn't make the </div>.  The problem is that
> there's no mechanism to "xo" that your output line is continued
> from the previous one, and since "xo" is stateless, it will happily
> start the next chunk of output with a new open div.  I'll add a
> "--continuation" option. (#58)
>
> >"bhyve": {
> >  "machines": {
> >    "machine": {
> >      "name": "test1",
> >      "memory": "2GB"
> >    }    "machine": {
> >      "name": "test2",
> >      "memory": "4GB"
> >    }
> >  }
> >}
>
> There's an "xo" option called "--not-first" for exactly these
> situations; place that option on the second invocation so it will
> know to emit the leading comma.  This should be documented (#59).
>
> >1) The entire document needs to be inside braces "{}" so that "bhyve" is a
> >member of an object.
>
> "xo" doesn't currently do this, since it assume you're generating
> JSON piecemeal and have a better idea that it of what you want
> to do with the output, but I've opened issue #60 for adding
> a "--object-wrapper" option that will perform this.
>
> >2) There's a missing comma between the two machine entries
>
> The "--not-first" option will repair this.
>
> >3) "machines" is an object, which erroneously contains 2 "machine" keys
>
> This is a bug.  "xo" lacks a means of knowing that an object is a
> list.  One might expect that labeling "name as a key would perform
> this, but it doesn't, and it's not clear that this is enough
> information.  Since "xo" is stateless, it cannot really handle
> that "--wrapper machine" applies only to the first item.  It
> would have to know not to generate the closing "}" for machine,
> but it's stateless, so I'd need a means of telling it that.
>
> In C code, we have "xo_open_list" and "xo_open_instance", like:
>
>
> https://libxo.readthedocs.io/en/latest/api.html?highlight=xo_open_instance#lists-and-instances
>
> But with "xo" I don't have lists and instances.  I'll need to
> find a means of adding these, though that would make "xo" more
> cumbersome and it would lack the FSM (and the stack) that catches
> missing calls in libxo.
>
>     xo $opts --open-list machine
>     for name in red green blue; do
>         xo $opts --open-instance machine
>         xo $opts "Machine {k:name} has {:memory}\n" $name `get-mem ~name`
>         xo $opts --close-instance machine
>     done
>     xo $opts --close-list machine
>
> Which is very exact but less that beautiful.  This is #61.
>
> Thanks,
>  Phil
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANV9Nzm9MKkUy%2B0bH_bQpOiey1MKk7q0_z2cauF4L185ujPQYQ>