Hello community,

here is the log from the commit of package python-yq for openSUSE:Factory 
checked in at 2020-03-05 23:22:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-yq (Old)
 and      /work/SRC/openSUSE:Factory/.python-yq.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-yq"

Thu Mar  5 23:22:27 2020 rev:6 rq:781772 version:2.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-yq/python-yq.changes      2019-10-31 
18:18:21.662203418 +0100
+++ /work/SRC/openSUSE:Factory/.python-yq.new.26092/python-yq.changes   
2020-03-05 23:22:34.541320600 +0100
@@ -1,0 +2,11 @@
+Thu Mar  5 08:32:23 UTC 2020 - Tomáš Chvátal <[email protected]>
+
+- Update to 2.10.0:
+  * Add support for in-place editing (yq -yi)
+  * Add argcomplete integration
+  * Docs: Migrate from RTD to gh-pages
+  * Add -Y/--yaml-roundtrip for preserving YAML styles and tags
+- Add patch to work with new PyYAML:
+  * pyaml53.patch
+
+-------------------------------------------------------------------

Old:
----
  yq-2.8.1.tar.gz

New:
----
  pyaml53.patch
  yq-2.10.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-yq.spec ++++++
--- /var/tmp/diff_new_pack.TBMOKj/_old  2020-03-05 23:22:38.313322673 +0100
+++ /var/tmp/diff_new_pack.TBMOKj/_new  2020-03-05 23:22:38.317322676 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-yq
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,17 +18,19 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-yq
-Version:        2.8.1
+Version:        2.10.0
 Release:        0
 Summary:        Command-line YAML processor - jq wrapper for YAML documents
 License:        Apache-2.0
 URL:            https://github.com/kislyuk/yq
 Source:         
https://files.pythonhosted.org/packages/source/y/yq/yq-%{version}.tar.gz
+Patch0:         pyaml53.patch
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 Requires:       jq
 Requires:       python-PyYAML >= 3.11
+Requires:       python-argcomplete >= 1.8.1
 Requires:       python-setuptools
 Requires:       python-toml >= 0.9.4
 Requires:       python-xmltodict >= 0.11.0
@@ -37,6 +39,7 @@
 BuildArch:      noarch
 # SECTION test requirements
 BuildRequires:  %{python_module PyYAML >= 3.11}
+BuildRequires:  %{python_module argcomplete >= 1.8.1}
 BuildRequires:  %{python_module toml >= 0.9.4}
 BuildRequires:  %{python_module xmltodict >= 0.11.0}
 BuildRequires:  jq
@@ -48,6 +51,7 @@
 
 %prep
 %setup -q -n yq-%{version}
+%patch0 -p1
 
 %build
 %python_build

++++++ pyaml53.patch ++++++
>From 5754ef46981d688dd249f96fc55ceaf4cd51f130 Mon Sep 17 00:00:00 2001
From: "Daniel M. Capella" <[email protected]>
Date: Sat, 29 Feb 2020 16:10:50 -0500
Subject: [PATCH] Fix test_datetimes for PyYAML >=5.3

https://github.com/yaml/pyyaml/pull/163
---
 test/test.py | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/test/test.py b/test/test.py
index 12fa806..8897196 100755
--- a/test/test.py
+++ b/test/test.py
@@ -3,7 +3,7 @@
 
 from __future__ import absolute_import, division, print_function, 
unicode_literals
 
-import os, sys, unittest, tempfile, json, io, platform, subprocess
+import os, sys, unittest, tempfile, json, io, platform, subprocess, yaml
 
 sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 
'..')))
 from yq import yq, cli  # noqa
@@ -116,7 +116,10 @@ def test_multidocs(self):
 
     def test_datetimes(self):
         self.assertEqual(self.run_yq("- 2016-12-20T22:07:36Z\n", ["."]), "")
-        self.assertEqual(self.run_yq("- 2016-12-20T22:07:36Z\n", ["-y", "."]), 
"- '2016-12-20T22:07:36'\n")
+        if yaml.__version__ < '5.3':
+            self.assertEqual(self.run_yq("- 2016-12-20T22:07:36Z\n", ["-y", 
"."]), "- '2016-12-20T22:07:36'\n")
+        else:
+            self.assertEqual(self.run_yq("- 2016-12-20T22:07:36Z\n", ["-y", 
"."]), "- '2016-12-20T22:07:36+00:00'\n")
 
         self.assertEqual(self.run_yq("2016-12-20", ["."]), "")
         self.assertEqual(self.run_yq("2016-12-20", ["-y", "."]), 
"'2016-12-20'\n")
++++++ yq-2.8.1.tar.gz -> yq-2.10.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/PKG-INFO new/yq-2.10.0/PKG-INFO
--- old/yq-2.8.1/PKG-INFO       2019-10-28 17:16:45.000000000 +0100
+++ new/yq-2.10.0/PKG-INFO      2019-12-23 17:52:29.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: yq
-Version: 2.8.1
+Version: 2.10.0
 Summary: Command-line YAML/XML processor - jq wrapper for YAML/XML documents
 Home-page: https://github.com/kislyuk/yq
 Author: Andrey Kislyuk
@@ -31,20 +31,81 @@
         
             yq .foo.bar input.yml
         
-        By default, no conversion of ``jq`` output is done. Use the 
``--yaml-output``/``-y`` argument to convert it back into YAML::
+        By default, no conversion of ``jq`` output is done. Use the 
``--yaml-output``/``-y`` option to convert it back into YAML::
         
             cat input.yml | yq -y .foo.bar
         
-        Use the ``--width``/``-w`` argument to pass the line wrap width for 
string literals. All other command line arguments are
-        forwarded to ``jq``. ``yq`` forwards the exit code ``jq`` produced, 
unless there was an error in YAML parsing, in which case
-        the exit code is 1. See the `jq manual 
<https://stedolan.github.io/jq/manual/>`_ for more details on ``jq`` features 
and
-        options.
-        
-        YAML `tags <http://www.yaml.org/spec/1.2/spec.html#id2764295>`_ in the 
input are ignored (any nested data is treated as
-        untagged). Key order is preserved.
+        Mapping key order is preserved. By default, custom `YAML tags 
<http://www.yaml.org/spec/1.2/spec.html#id2764295>`_ and
+        `styles <https://yaml.org/spec/current.html#id2509255>`_ in the input 
are ignored. Use the ``--yaml-roundtrip``/``-Y``
+        option to preserve YAML tags and styles by representing them as extra 
items in their enclosing mappings and sequences
+        while in JSON::
+        
+            yq -Y .foo.bar input.yml
+        
+        Use the ``--width``/``-w`` option to pass the line wrap width for 
string literals. With ``-y/-Y``, files can be edited
+        in place like with ``sed -i``: ``yq -yi .foo=1 *.yml``. All other 
command line arguments are forwarded to ``jq``. ``yq``
+        forwards the exit code ``jq`` produced, unless there was an error in 
YAML parsing, in which case the exit code is 1.
+        See the `jq manual <https://stedolan.github.io/jq/manual/>`_ for more 
details on ``jq`` features and options.
         
         Because YAML treats JSON as a dialect of YAML, you can use yq to 
convert JSON to YAML: ``yq -y . < in.json > out.yml``.
         
+        Preserving tags and styles using the ``-Y`` (``--yaml-roundtrip``) 
option
+        
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        
+        The ``-Y`` option helps preserve custom `string styles 
<https://yaml-multiline.info/>`_ and
+        `tags <https://camel.readthedocs.io/en/latest/yamlref.html#tags>`_ in 
your document. For exmaple, consider the following
+        document (an `AWS CloudFormation 
<https://aws.amazon.com/cloudformation/>`_ template fragment)::
+        
+            Resources:
+              ElasticLoadBalancer:
+                Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
+                Properties:
+                  AvailabilityZones: !GetAZs ''
+                  Instances:
+                    - !Ref Ec2Instance1
+                    - !Ref Ec2Instance2
+                  Description: >-
+                    Load balancer for Big Important Service.
+        
+                    Good thing it's managed by this template.
+        
+        Passing this document through ``yq -y .Resources.ElasticLoadBalancer`` 
will drop custom tags, such as ``!Ref``,
+        and styles, such as the `folded <https://yaml-multiline.info/>`_ style 
of the ``Description`` field::
+        
+            Type: AWS::ElasticLoadBalancing::LoadBalancer
+            Properties:
+              AvailabilityZones: ''
+              Instances:
+                - Ec2Instance1
+                - Ec2Instance2
+              Description: 'Load balancer for Big Important Service.
+        
+                Good thing it''s managed by this template.'
+        
+        By contrast, passing it through ``yq -Y 
.Resources.ElasticLoadBalancer`` will preserve tags and styles::
+        
+            Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
+            Properties:
+              AvailabilityZones: !GetAZs ''
+              Instances:
+                - !Ref 'Ec2Instance1'
+                - !Ref 'Ec2Instance2'
+              Description: >-
+                Load balancer for Big Important Service.
+        
+                Good thing it's managed by this template.
+        
+        To accomplish this in ``-Y`` mode, yq carries extra metadata (mapping 
pairs and sequence values) in the JSON
+        representation of your document for any custom tags or styles that it 
finds. When converting the JSON back into YAML, it
+        parses this metadata, re-applies the tags and styles, and discards the 
extra pairs and values.
+        
+        .. warning ::
+        
+         The ``-Y`` option is incompatible with jq filters that do not expect 
the extra information injected into the document
+         to preserve the YAML formatting. For example, a jq filter that counts 
entries in the Instances array will come up with
+         4 entries instead of 2. A filter that expects all array entries to be 
mappings may break due to the presence of string
+         metadata keys. Check your jq filter for compatibility/semantic 
validity when using the ``-Y`` option.
+        
         XML support
         -----------
         ``yq`` also supports XML. The ``yq`` package installs an executable, 
``xq``, which
@@ -67,7 +128,7 @@
         Links
         -----
         * `Project home page (GitHub) <https://github.com/kislyuk/yq>`_
-        * `Documentation (Read the Docs) 
<https://yq.readthedocs.io/en/latest/>`_
+        * `Documentation <https://kislyuk.github.io/yq/>`_
         * `Package distribution (PyPI) <https://pypi.python.org/pypi/yq>`_
         * `Change log <https://github.com/kislyuk/yq/blob/master/Changes.rst>`_
         * `jq <https://stedolan.github.io/jq/>`_ - the command-line JSON 
processor utility powering ``yq``
@@ -80,16 +141,14 @@
         -------
         Licensed under the terms of the `Apache License, Version 2.0 
<http://www.apache.org/licenses/LICENSE-2.0>`_.
         
-        .. image:: https://img.shields.io/travis/kislyuk/yq.svg
-                :target: https://travis-ci.org/kislyuk/yq
+        .. image:: 
https://github.com/kislyuk/yq/workflows/Python%20package/badge.svg
+                :target: https://github.com/kislyuk/yq/actions
         .. image:: 
https://codecov.io/github/kislyuk/yq/coverage.svg?branch=master
                 :target: https://codecov.io/github/kislyuk/yq?branch=master
         .. image:: https://img.shields.io/pypi/v/yq.svg
                 :target: https://pypi.python.org/pypi/yq
         .. image:: https://img.shields.io/pypi/l/yq.svg
                 :target: https://pypi.python.org/pypi/yq
-        .. image:: https://readthedocs.org/projects/yq/badge/?version=latest
-                :target: https://yq.readthedocs.io/
         
 Platform: UNKNOWN
 Classifier: Intended Audience :: Developers
@@ -98,10 +157,10 @@
 Classifier: Operating System :: POSIX
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Provides-Extra: test
 Provides-Extra: toml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/README.rst new/yq-2.10.0/README.rst
--- old/yq-2.8.1/README.rst     2019-10-16 18:29:39.000000000 +0200
+++ new/yq-2.10.0/README.rst    2019-12-23 17:43:58.000000000 +0100
@@ -23,20 +23,81 @@
 
     yq .foo.bar input.yml
 
-By default, no conversion of ``jq`` output is done. Use the 
``--yaml-output``/``-y`` argument to convert it back into YAML::
+By default, no conversion of ``jq`` output is done. Use the 
``--yaml-output``/``-y`` option to convert it back into YAML::
 
     cat input.yml | yq -y .foo.bar
 
-Use the ``--width``/``-w`` argument to pass the line wrap width for string 
literals. All other command line arguments are
-forwarded to ``jq``. ``yq`` forwards the exit code ``jq`` produced, unless 
there was an error in YAML parsing, in which case
-the exit code is 1. See the `jq manual 
<https://stedolan.github.io/jq/manual/>`_ for more details on ``jq`` features 
and
-options.
-
-YAML `tags <http://www.yaml.org/spec/1.2/spec.html#id2764295>`_ in the input 
are ignored (any nested data is treated as
-untagged). Key order is preserved.
+Mapping key order is preserved. By default, custom `YAML tags 
<http://www.yaml.org/spec/1.2/spec.html#id2764295>`_ and
+`styles <https://yaml.org/spec/current.html#id2509255>`_ in the input are 
ignored. Use the ``--yaml-roundtrip``/``-Y``
+option to preserve YAML tags and styles by representing them as extra items in 
their enclosing mappings and sequences
+while in JSON::
+
+    yq -Y .foo.bar input.yml
+
+Use the ``--width``/``-w`` option to pass the line wrap width for string 
literals. With ``-y/-Y``, files can be edited
+in place like with ``sed -i``: ``yq -yi .foo=1 *.yml``. All other command line 
arguments are forwarded to ``jq``. ``yq``
+forwards the exit code ``jq`` produced, unless there was an error in YAML 
parsing, in which case the exit code is 1.
+See the `jq manual <https://stedolan.github.io/jq/manual/>`_ for more details 
on ``jq`` features and options.
 
 Because YAML treats JSON as a dialect of YAML, you can use yq to convert JSON 
to YAML: ``yq -y . < in.json > out.yml``.
 
+Preserving tags and styles using the ``-Y`` (``--yaml-roundtrip``) option
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``-Y`` option helps preserve custom `string styles 
<https://yaml-multiline.info/>`_ and
+`tags <https://camel.readthedocs.io/en/latest/yamlref.html#tags>`_ in your 
document. For exmaple, consider the following
+document (an `AWS CloudFormation <https://aws.amazon.com/cloudformation/>`_ 
template fragment)::
+
+    Resources:
+      ElasticLoadBalancer:
+        Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
+        Properties:
+          AvailabilityZones: !GetAZs ''
+          Instances:
+            - !Ref Ec2Instance1
+            - !Ref Ec2Instance2
+          Description: >-
+            Load balancer for Big Important Service.
+
+            Good thing it's managed by this template.
+
+Passing this document through ``yq -y .Resources.ElasticLoadBalancer`` will 
drop custom tags, such as ``!Ref``,
+and styles, such as the `folded <https://yaml-multiline.info/>`_ style of the 
``Description`` field::
+
+    Type: AWS::ElasticLoadBalancing::LoadBalancer
+    Properties:
+      AvailabilityZones: ''
+      Instances:
+        - Ec2Instance1
+        - Ec2Instance2
+      Description: 'Load balancer for Big Important Service.
+
+        Good thing it''s managed by this template.'
+
+By contrast, passing it through ``yq -Y .Resources.ElasticLoadBalancer`` will 
preserve tags and styles::
+
+    Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
+    Properties:
+      AvailabilityZones: !GetAZs ''
+      Instances:
+        - !Ref 'Ec2Instance1'
+        - !Ref 'Ec2Instance2'
+      Description: >-
+        Load balancer for Big Important Service.
+
+        Good thing it's managed by this template.
+
+To accomplish this in ``-Y`` mode, yq carries extra metadata (mapping pairs 
and sequence values) in the JSON
+representation of your document for any custom tags or styles that it finds. 
When converting the JSON back into YAML, it
+parses this metadata, re-applies the tags and styles, and discards the extra 
pairs and values.
+
+.. warning ::
+
+ The ``-Y`` option is incompatible with jq filters that do not expect the 
extra information injected into the document
+ to preserve the YAML formatting. For example, a jq filter that counts entries 
in the Instances array will come up with
+ 4 entries instead of 2. A filter that expects all array entries to be 
mappings may break due to the presence of string
+ metadata keys. Check your jq filter for compatibility/semantic validity when 
using the ``-Y`` option.
+
 XML support
 -----------
 ``yq`` also supports XML. The ``yq`` package installs an executable, ``xq``, 
which
@@ -59,7 +120,7 @@
 Links
 -----
 * `Project home page (GitHub) <https://github.com/kislyuk/yq>`_
-* `Documentation (Read the Docs) <https://yq.readthedocs.io/en/latest/>`_
+* `Documentation <https://kislyuk.github.io/yq/>`_
 * `Package distribution (PyPI) <https://pypi.python.org/pypi/yq>`_
 * `Change log <https://github.com/kislyuk/yq/blob/master/Changes.rst>`_
 * `jq <https://stedolan.github.io/jq/>`_ - the command-line JSON processor 
utility powering ``yq``
@@ -72,13 +133,11 @@
 -------
 Licensed under the terms of the `Apache License, Version 2.0 
<http://www.apache.org/licenses/LICENSE-2.0>`_.
 
-.. image:: https://img.shields.io/travis/kislyuk/yq.svg
-        :target: https://travis-ci.org/kislyuk/yq
+.. image:: https://github.com/kislyuk/yq/workflows/Python%20package/badge.svg
+        :target: https://github.com/kislyuk/yq/actions
 .. image:: https://codecov.io/github/kislyuk/yq/coverage.svg?branch=master
         :target: https://codecov.io/github/kislyuk/yq?branch=master
 .. image:: https://img.shields.io/pypi/v/yq.svg
         :target: https://pypi.python.org/pypi/yq
 .. image:: https://img.shields.io/pypi/l/yq.svg
         :target: https://pypi.python.org/pypi/yq
-.. image:: https://readthedocs.org/projects/yq/badge/?version=latest
-        :target: https://yq.readthedocs.io/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/setup.py new/yq-2.10.0/setup.py
--- old/yq-2.8.1/setup.py       2019-10-28 17:16:14.000000000 +0100
+++ new/yq-2.10.0/setup.py      2019-12-23 17:47:08.000000000 +0100
@@ -6,7 +6,7 @@
 
 setup(
     name="yq",
-    version="2.8.1",
+    version="2.10.0",
     url="https://github.com/kislyuk/yq";,
     license="Apache Software License",
     author="Andrey Kislyuk",
@@ -16,7 +16,8 @@
     install_requires=[
         "setuptools",
         "PyYAML >= 3.11",
-        "xmltodict >= 0.11.0"
+        "xmltodict >= 0.11.0",
+        "argcomplete >= 1.8.1"
     ],
     tests_require=tests_require,
     extras_require={
@@ -39,10 +40,10 @@
         "Operating System :: POSIX",
         "Programming Language :: Python",
         "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3.3",
-        "Programming Language :: Python :: 3.4",
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
         "Topic :: Software Development :: Libraries :: Python Modules"
     ]
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/test/bomb.yml new/yq-2.10.0/test/bomb.yml
--- old/yq-2.8.1/test/bomb.yml  1970-01-01 01:00:00.000000000 +0100
+++ new/yq-2.10.0/test/bomb.yml 2019-11-30 16:47:11.000000000 +0100
@@ -0,0 +1,9 @@
+a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
+b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
+c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
+d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
+e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
+f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
+g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
+h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
+i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/test/cfn.yml new/yq-2.10.0/test/cfn.yml
--- old/yq-2.8.1/test/cfn.yml   1970-01-01 01:00:00.000000000 +0100
+++ new/yq-2.10.0/test/cfn.yml  2019-11-06 23:54:40.000000000 +0100
@@ -0,0 +1,92 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Metadata:
+  License: Apache-2.0
+Description: 'AWS CloudFormation Sample Template 
S3_Website_With_CloudFront_Distribution:
+  Sample template showing how to create a website with a custom DNS name, 
hosted on
+  Amazon S3 and served via Amazone CloudFront. It assumes you already have a 
Hosted
+  Zone registered with Amazon Route 53. **WARNING** This template creates an 
Amazon
+  Route 53 DNS record, an S3 bucket and a CloudFront distribution. You will be 
billed
+  for the AWS resources used if you create a stack from this template.'
+Parameters:
+  HostedZone:
+    Type: String
+    Description: The DNS name of an existing Amazon Route 53 hosted zone
+    AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
+    ConstraintDescription: must be a valid DNS zone name.
+Mappings:
+  Region2S3WebsiteSuffix:
+    us-east-1:
+      Suffix: .s3-website-us-east-1.amazonaws.com
+    us-west-1:
+      Suffix: .s3-website-us-west-1.amazonaws.com
+    us-west-2:
+      Suffix: .s3-website-us-west-2.amazonaws.com
+    eu-west-1:
+      Suffix: .s3-website-eu-west-1.amazonaws.com
+    ap-northeast-1:
+      Suffix: .s3-website-ap-northeast-1.amazonaws.com
+    ap-northeast-2:
+      Suffix: .s3-website-ap-northeast-2.amazonaws.com
+    ap-southeast-1:
+      Suffix: .s3-website-ap-southeast-1.amazonaws.com
+    ap-southeast-2:
+      Suffix: .s3-website-ap-southeast-2.amazonaws.com
+    ap-south-1:
+      Suffix: .s3-website-ap-south-1.amazonaws.com
+    us-east-2:
+      Suffix: .s3-website-us-east-2.amazonaws.com
+    sa-east-1:
+      Suffix: .s3-website-sa-east-1.amazonaws.com
+    cn-north-1:
+      Suffix: .s3-website.cn-north-1.amazonaws.com.cn
+    eu-central-1:
+      Suffix: .s3-website.eu-central-1.amazonaws.com
+Resources:
+  S3BucketForWebsiteContent:
+    Type: AWS::S3::Bucket
+    Properties:
+      AccessControl: PublicRead
+      WebsiteConfiguration:
+        IndexDocument: index.html
+        ErrorDocument: error.html
+  WebsiteCDN:
+    Type: AWS::CloudFront::Distribution
+    Properties:
+      DistributionConfig:
+        Comment: CDN for S3-backed website
+        Aliases:
+          - !Join ['', [!Ref 'AWS::StackName', !Ref 'AWS::AccountId', ., !Ref 
'AWS::Region',
+              ., !Ref 'HostedZone']]
+        Enabled: 'true'
+        DefaultCacheBehavior:
+          ForwardedValues:
+            QueryString: 'true'
+          TargetOriginId: only-origin
+          ViewerProtocolPolicy: allow-all
+        DefaultRootObject: index.html
+        Origins:
+          - CustomOriginConfig:
+              HTTPPort: '80'
+              HTTPSPort: '443'
+              OriginProtocolPolicy: http-only
+            DomainName: !Join ['', [!Ref 'S3BucketForWebsiteContent', 
!FindInMap [
+                  Region2S3WebsiteSuffix, !Ref 'AWS::Region', Suffix]]]
+            Id: only-origin
+  WebsiteDNSName:
+    Type: AWS::Route53::RecordSet
+    Properties:
+      HostedZoneName: !Join ['', [!Ref 'HostedZone', .]]
+      Comment: CNAME redirect custom name to CloudFront distribution
+      Name: !Join ['', [!Ref 'AWS::StackName', !Ref 'AWS::AccountId', ., !Ref 
'AWS::Region',
+          ., !Ref 'HostedZone']]
+      Type: CNAME
+      TTL: '900'
+      ResourceRecords:
+        - !GetAtt [WebsiteCDN, DomainName]
+Outputs:
+  WebsiteURL:
+    Value: !Join ['', ['http://', !Ref 'WebsiteDNSName']]
+    Description: The URL of the newly created website
+  BucketName:
+    Value: !Ref 'S3BucketForWebsiteContent'
+    Description: Name of S3 bucket to hold website content
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/test/test.py new/yq-2.10.0/test/test.py
--- old/yq-2.8.1/test/test.py   2019-10-28 16:41:04.000000000 +0100
+++ new/yq-2.10.0/test/test.py  2019-12-23 17:38:41.000000000 +0100
@@ -131,6 +131,29 @@
             tf.seek(0)
             self.assertEqual(self.run_yq("", ["-y", ".xyz.foo", 
self.fd_path(tf)]), 'bar\n...\n')
 
+    def test_roundtrip_yaml(self):
+        cfn_filename = os.path.join(os.path.dirname(__file__), "cfn.yml")
+        with io.open(cfn_filename) as fh:
+            self.assertEqual(self.run_yq("", ["-Y", ".", cfn_filename]), 
fh.read())
+
+    @unittest.skipIf(sys.version_info < (3, 5), "Skipping feature incompatible 
with Python 2")
+    def test_in_place(self):
+        with tempfile.NamedTemporaryFile() as tf, 
tempfile.NamedTemporaryFile() as tf2:
+            tf.write(b"- foo\n- bar\n")
+            tf.seek(0)
+            tf2.write(b"- foo\n- bar\n")
+            tf2.seek(0)
+            self.run_yq("", ["-i", "-y", ".[0]", tf.name, tf2.name])
+            self.assertEqual(tf.read(), b'foo\n...\n')
+            self.assertEqual(tf2.read(), b'foo\n...\n')
+
+            # Files do not get overwritten on error (DeferredOutputStream 
logic)
+            self.run_yq("", ["-i", "-y", tf.name, tf2.name], 
expect_exit_codes=[3])
+            tf.seek(0)
+            tf2.seek(0)
+            self.assertEqual(tf.read(), b'foo\n...\n')
+            self.assertEqual(tf2.read(), b'foo\n...\n')
+
     @unittest.expectedFailure
     def test_times(self):
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq/__init__.py new/yq-2.10.0/yq/__init__.py
--- old/yq-2.8.1/yq/__init__.py 2019-10-28 16:32:15.000000000 +0100
+++ new/yq-2.10.0/yq/__init__.py        2019-12-23 17:39:16.000000000 +0100
@@ -5,34 +5,21 @@
 See https://github.com/kislyuk/yq for more information.
 """
 
+# PYTHON_ARGCOMPLETE_OK
+
 from __future__ import absolute_import, division, print_function, 
unicode_literals
 
 import sys, argparse, subprocess, json
 from collections import OrderedDict
 from datetime import datetime, date, time
 
-import yaml
-
-from .version import __version__
+import yaml, argcomplete
 
-class Parser(argparse.ArgumentParser):
-    def print_help(self):
-        yq_help = argparse.ArgumentParser.format_help(self).splitlines()
-        print("\n".join(["usage: yq [options] <jq filter> [YAML file...]"] + 
yq_help[1:] + [""]))
-        try:
-            subprocess.check_call(["jq", "--help"])
-        except Exception:
-            pass
-
-class OrderedLoader(yaml.SafeLoader):
-    pass
-
-class OrderedIndentlessDumper(yaml.SafeDumper):
-    pass
-
-class OrderedDumper(yaml.SafeDumper):
-    def increase_indent(self, flow=False, indentless=False):
-        return super(OrderedDumper, self).increase_indent(flow, False)
+from .compat import USING_PYTHON2, open
+from .parser import get_parser, jq_arg_spec
+from .loader import get_loader
+from .dumper import get_dumper
+from .version import __version__  # noqa
 
 class JSONDateTimeEncoder(json.JSONEncoder):
     def default(self, o):
@@ -40,104 +27,57 @@
             return o.isoformat()
         return json.JSONEncoder.default(self, o)
 
-def construct_mapping(loader, node):
-    loader.flatten_mapping(node)
-    return OrderedDict(loader.construct_pairs(node))
-
-def represent_dict_order(dumper, data):
-    return dumper.represent_mapping("tag:yaml.org,2002:map", data.items())
-
 def decode_docs(jq_output, json_decoder):
     while jq_output:
         doc, pos = json_decoder.raw_decode(jq_output)
         jq_output = jq_output[pos + 1:]
         yield doc
 
-def parse_unknown_tags(loader, tag_suffix, node):
-    if isinstance(node, yaml.nodes.ScalarNode):
-        return loader.construct_scalar(node)
-    elif isinstance(node, yaml.nodes.SequenceNode):
-        return loader.construct_sequence(node)
-    elif isinstance(node, yaml.nodes.MappingNode):
-        return construct_mapping(loader, node)
-
-OrderedLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, 
construct_mapping)
-OrderedLoader.add_multi_constructor('', parse_unknown_tags)
-
-for dumper in OrderedIndentlessDumper, OrderedDumper:
-    dumper.add_representer(OrderedDict, represent_dict_order)
-
-# jq arguments that consume positionals must be listed here to avoid our 
parser mistaking them for our positionals
-jq_arg_spec = {"--indent": 1, "-f": 1, "--from-file": 1, "-L": 1, "--arg": 2, 
"--argjson": 2, "--slurpfile": 2,
-               "--argfile": 2, "--rawfile": 2, "--args": argparse.REMAINDER, 
"--jsonargs": argparse.REMAINDER}
-
-# Detection for Python 2
-USING_PYTHON2 = True if sys.version_info < (3, 0) else False
-
-def get_parser(program_name):
-    # By default suppress these help strings and only enable them in the 
specific programs.
-    yaml_output_help, width_help, indentless_help = argparse.SUPPRESS, 
argparse.SUPPRESS, argparse.SUPPRESS
-    xml_output_help, xml_dtd_help, xml_root_help = argparse.SUPPRESS, 
argparse.SUPPRESS, argparse.SUPPRESS
-    toml_output_help = argparse.SUPPRESS
-
-    if program_name == "yq":
-        current_language = "YAML"
-        yaml_output_help = "Transcode jq JSON output back into YAML and emit 
it"
-        width_help = "When using --yaml-output, specify string wrap width"
-        indentless_help = 'When using --yaml-output, indent block style lists 
(sequences) with 0 spaces instead of 2'
-    elif program_name == "xq":
-        current_language = "XML"
-        xml_output_help = "Transcode jq JSON output back into XML and emit it"
-        xml_dtd_help = "Preserve XML Document Type Definition (disables 
streaming of multiple docs)"
-        xml_root_help = "When transcoding back to XML, envelope the output in 
an element with this name"
-    elif program_name == "tq":
-        current_language = "TOML"
-        toml_output_help = "Transcode jq JSON output back into TOML and emit 
it"
-    else:
-        raise Exception("Unknown program name")
-
-    description = __doc__.replace("yq", program_name).replace("YAML", 
current_language)
-    parser_args = dict(prog=program_name, description=description, 
formatter_class=argparse.RawTextHelpFormatter)
-    if sys.version_info >= (3, 5):
-        parser_args.update(allow_abbrev=False)  # required to disambiguate 
options listed in jq_arg_spec
-    parser = Parser(**parser_args)
-    parser.add_argument("--output-format", default="json", 
help=argparse.SUPPRESS)
-    parser.add_argument("--yaml-output", "--yml-output", "-y", 
dest="output_format", action="store_const", const="yaml",
-                        help=yaml_output_help)
-    parser.add_argument("--width", "-w", type=int, help=width_help)
-    parser.add_argument("--indentless-lists", "--indentless", 
action="store_true", help=indentless_help)
-    parser.add_argument("--xml-output", "-x", dest="output_format", 
action="store_const", const="xml",
-                        help=xml_output_help)
-    parser.add_argument("--xml-dtd", action="store_true", help=xml_dtd_help)
-    parser.add_argument("--xml-root", help=xml_root_help)
-    parser.add_argument("--toml-output", "-t", dest="output_format", 
action="store_const", const="toml",
-                        help=toml_output_help)
-    parser.add_argument("--version", action="version", version="%(prog)s 
{version}".format(version=__version__))
-
-    for arg in jq_arg_spec:
-        parser.add_argument(arg, nargs=jq_arg_spec[arg], dest=arg, 
action="append", help=argparse.SUPPRESS)
-
-    parser.add_argument("jq_filter")
-    parser.add_argument("input_streams", nargs="*", type=argparse.FileType(), 
metavar="files", default=[sys.stdin])
-    return parser
-
 def xq_cli():
     cli(input_format="xml", program_name="xq")
 
 def tq_cli():
     cli(input_format="toml", program_name="tq")
 
+class DeferredOutputStream:
+    def __init__(self, name, mode="w"):
+        self.name = name
+        self.mode = mode
+        self._fh = None
+
+    @property
+    def fh(self):
+        if self._fh is None:
+            self._fh = open(self.name, self.mode)
+        return self._fh
+
+    def flush(self):
+        if self._fh is not None:
+            return self.fh.flush()
+
+    def close(self):
+        if self._fh is not None:
+            return self.fh.close()
+
+    def __getattr__(self, a):
+        return getattr(self.fh, a)
+
 def cli(args=None, input_format="yaml", program_name="yq"):
-    parser = get_parser(program_name)
+    parser = get_parser(program_name, __doc__)
+    argcomplete.autocomplete(parser)
     args, jq_args = parser.parse_known_args(args=args)
 
     for i, arg in enumerate(jq_args):
         if arg.startswith("-") and not arg.startswith("--"):
+            if "i" in arg:
+                args.in_place = True
             if "y" in arg:
                 args.output_format = "yaml"
+            elif "Y" in arg:
+                args.output_format = "annotated_yaml"
             elif "x" in arg:
                 args.output_format = "xml"
-            jq_args[i] = arg.replace("x", "").replace("y", "")
+            jq_args[i] = arg.replace("i", "").replace("x", "").replace("y", 
"").replace("Y", "")
         if args.output_format != "json":
             jq_args[i] = jq_args[i].replace("C", "")
             if jq_args[i] == "-":
@@ -163,15 +103,35 @@
             jq_filter_arg_loc = jq_args.index('--jsonargs') + 1
         jq_args.insert(jq_filter_arg_loc, args.jq_filter)
     delattr(args, "jq_filter")
+    in_place = args.in_place
+    delattr(args, "in_place")
 
     if sys.stdin.isatty() and not args.input_streams:
         return parser.print_help()
 
-    yq(input_format=input_format, program_name=program_name, jq_args=jq_args, 
**vars(args))
+    yq_args = dict(input_format=input_format, program_name=program_name, 
jq_args=jq_args, **vars(args))
+    if in_place:
+        if USING_PYTHON2:
+            sys.exit("{}: -i/--in-place is not compatible with Python 
2".format(program_name))
+        if args.output_format not in {"yaml", "annotated_yaml"}:
+            sys.exit("{}: -i/--in-place can only be used with 
-y/-Y".format(program_name))
+        input_streams = yq_args.pop("input_streams")
+        if len(input_streams) == 1 and input_streams[0].name == "<stdin>":
+            msg = "{}: -i/--in-place can only be used with filename arguments, 
not on standard input"
+            sys.exit(msg.format(program_name))
+        for i, input_stream in enumerate(input_streams):
+            def exit_handler(arg=None):
+                if arg:
+                    sys.exit(arg)
+            if i < len(input_streams):
+                yq_args["exit_func"] = exit_handler
+            yq(input_streams=[input_stream], 
output_stream=DeferredOutputStream(input_stream.name), **yq_args)
+    else:
+        yq(**yq_args)
 
 def yq(input_streams=None, output_stream=None, input_format="yaml", 
output_format="json",
-       program_name="yq", width=None, indentless_lists=False, xml_root=None, 
xml_dtd=False, jq_args=frozenset(),
-       exit_func=None):
+       program_name="yq", width=None, indentless_lists=False, xml_root=None, 
xml_dtd=False,
+       jq_args=frozenset(), exit_func=None):
     if not input_streams:
         input_streams = [sys.stdin]
     if not output_stream:
@@ -195,10 +155,12 @@
             # TODO: enable true streaming in this branch (with asyncio, 
asyncproc, a multi-shot variant of
             # subprocess.Popen._communicate, etc.)
             # See 
https://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python
+            use_annotations = True if output_format == "annotated_yaml" else 
False
             input_docs = []
             for input_stream in input_streams:
                 if input_format == "yaml":
-                    input_docs.extend(yaml.load_all(input_stream, 
Loader=OrderedLoader))
+                    loader = get_loader(use_annotations=use_annotations)
+                    input_docs.extend(yaml.load_all(input_stream, 
Loader=loader))
                 elif input_format == "xml":
                     import xmltodict
                     input_docs.append(xmltodict.parse(input_stream.read(), 
disable_entities=True))
@@ -210,9 +172,9 @@
             input_payload = "\n".join(json.dumps(doc, cls=JSONDateTimeEncoder) 
for doc in input_docs)
             jq_out, jq_err = jq.communicate(input_payload)
             json_decoder = json.JSONDecoder(object_pairs_hook=OrderedDict)
-            if output_format == "yaml":
-                dumper_class = OrderedIndentlessDumper if indentless_lists 
else OrderedDumper
-                yaml.dump_all(decode_docs(jq_out, json_decoder), 
stream=output_stream, Dumper=dumper_class,
+            if output_format == "yaml" or output_format == "annotated_yaml":
+                yaml.dump_all(decode_docs(jq_out, json_decoder), 
stream=output_stream,
+                              
Dumper=get_dumper(use_annotations=use_annotations, indentless=indentless_lists),
                               width=width, allow_unicode=True, 
default_flow_style=False)
             elif output_format == "xml":
                 import xmltodict
@@ -249,8 +211,9 @@
                         toml.dump(doc, output_stream)
         else:
             if input_format == "yaml":
+                loader = get_loader(use_annotations=False)
                 for input_stream in input_streams:
-                    for doc in yaml.load_all(input_stream, 
Loader=OrderedLoader):
+                    for doc in yaml.load_all(input_stream, Loader=loader):
                         json.dump(doc, jq.stdin, cls=JSONDateTimeEncoder)
                         jq.stdin.write("\n")
             elif input_format == "xml":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq/compat.py new/yq-2.10.0/yq/compat.py
--- old/yq-2.8.1/yq/compat.py   1970-01-01 01:00:00.000000000 +0100
+++ new/yq-2.10.0/yq/compat.py  2019-12-23 17:34:12.000000000 +0100
@@ -0,0 +1,12 @@
+from __future__ import absolute_import, division, print_function, 
unicode_literals
+
+import sys, io
+
+USING_PYTHON2 = True if sys.version_info < (3, 0) else False
+
+if USING_PYTHON2:
+    str = unicode  # noqa
+    open = io.open
+else:
+    str = str
+    open = open
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq/dumper.py new/yq-2.10.0/yq/dumper.py
--- old/yq-2.8.1/yq/dumper.py   1970-01-01 01:00:00.000000000 +0100
+++ new/yq-2.10.0/yq/dumper.py  2019-11-04 19:36:00.000000000 +0100
@@ -0,0 +1,74 @@
+from __future__ import absolute_import, division, print_function, 
unicode_literals
+
+import re
+from collections import OrderedDict
+
+import yaml
+
+from .compat import str
+from .loader import hash_key
+
+class OrderedIndentlessDumper(yaml.SafeDumper):
+    pass
+
+class OrderedDumper(yaml.SafeDumper):
+    def increase_indent(self, flow=False, indentless=False):
+        return super(OrderedDumper, self).increase_indent(flow, False)
+
+yaml_value_annotation_re = 
re.compile(r"^__yq_(?P<type>tag|style)_(?P<key>.+)__$")
+yaml_item_annotation_re = 
re.compile(r"^__yq_(?P<type>tag|style)_(?P<key>\d+)_(?P<value>.+)__$")
+
+def get_dumper(use_annotations=False, indentless=False):
+    def represent_dict(dumper, data):
+        pairs, custom_styles, custom_tags = [], {}, {}
+        for k, v in data.items():
+            if use_annotations and isinstance(k, str):
+                value_annotation = yaml_value_annotation_re.match(k)
+                if value_annotation and value_annotation.group("type") == 
"style":
+                    custom_styles[value_annotation.group("key")] = v
+                    continue
+                elif value_annotation and value_annotation.group("type") == 
"tag":
+                    custom_tags[value_annotation.group("key")] = v
+                    continue
+            pairs.append((k, v))
+        mapping = dumper.represent_mapping("tag:yaml.org,2002:map", pairs)
+        if use_annotations:
+            for k, v in mapping.value:
+                hashed_key = hash_key(k.value)
+                if hashed_key in custom_styles:
+                    if isinstance(v, yaml.nodes.ScalarNode):
+                        v.style = custom_styles[hashed_key]
+                    elif custom_styles[hashed_key] == "flow":
+                        v.flow_style = True
+                if hashed_key in custom_tags:
+                    v.tag = custom_tags[hashed_key]
+        return mapping
+
+    def represent_list(dumper, data):
+        raw_list, custom_styles, custom_tags = [], {}, {}
+        for v in data:
+            if use_annotations and isinstance(v, str):
+                annotation = yaml_item_annotation_re.match(v)
+                if annotation and annotation.group("type") == "style":
+                    custom_styles[annotation.group("key")] = 
annotation.group("value")
+                    continue
+                elif annotation and annotation.group("type") == "tag":
+                    custom_tags[annotation.group("key")] = 
annotation.group("value")
+                    continue
+            raw_list.append(v)
+        sequence = dumper.represent_list(raw_list)
+        if use_annotations:
+            for i, v in enumerate(sequence.value):
+                if str(i) in custom_styles:
+                    if isinstance(v, yaml.nodes.ScalarNode):
+                        v.style = custom_styles[str(i)]
+                    elif custom_styles[str(i)] == "flow":
+                        v.flow_style = True
+                if str(i) in custom_tags:
+                    v.tag = custom_tags[str(i)]
+        return sequence
+
+    dumper = OrderedIndentlessDumper if indentless else OrderedDumper
+    dumper.add_representer(OrderedDict, represent_dict)
+    dumper.add_representer(list, represent_list)
+    return dumper
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq/loader.py new/yq-2.10.0/yq/loader.py
--- old/yq-2.8.1/yq/loader.py   1970-01-01 01:00:00.000000000 +0100
+++ new/yq-2.10.0/yq/loader.py  2019-12-01 16:52:31.000000000 +0100
@@ -0,0 +1,58 @@
+from __future__ import absolute_import, division, print_function, 
unicode_literals
+
+import yaml
+from base64 import b64encode
+from collections import OrderedDict
+from hashlib import sha224
+
+from .compat import str
+
+def hash_key(key):
+    return b64encode(sha224(key.encode() if isinstance(key, str) else 
key).digest()).decode()
+
+class OrderedLoader(yaml.SafeLoader):
+    pass
+
+def get_loader(use_annotations=False):
+    def construct_sequence(loader, node):
+        annotations = []
+        for i, v_node in enumerate(node.value):
+            if not use_annotations:
+                break
+            if v_node.tag and v_node.tag.startswith("!") and not 
v_node.tag.startswith("!!") and len(v_node.tag) > 1:
+                annotations.append("__yq_tag_{}_{}__".format(i, v_node.tag))
+            if isinstance(v_node, yaml.nodes.ScalarNode) and v_node.style:
+                annotations.append("__yq_style_{}_{}__".format(i, 
v_node.style))
+            elif isinstance(v_node, (yaml.nodes.SequenceNode, 
yaml.nodes.MappingNode)) and v_node.flow_style is True:
+                annotations.append("__yq_style_{}_{}__".format(i, "flow"))
+        return [loader.construct_object(i) for i in node.value] + annotations
+
+    def construct_mapping(loader, node):
+        loader.flatten_mapping(node)  # TODO: is this needed?
+        pairs = []
+        for k_node, v_node in node.value:
+            key = loader.construct_object(k_node)
+            value = loader.construct_object(v_node)
+            pairs.append((key, value))
+            if not (use_annotations and isinstance(key, (str, bytes))):
+                continue
+            if v_node.tag and v_node.tag.startswith("!") and not 
v_node.tag.startswith("!!") and len(v_node.tag) > 1:
+                pairs.append(("__yq_tag_{}__".format(hash_key(key)), 
v_node.tag))
+            if isinstance(v_node, yaml.nodes.ScalarNode) and v_node.style:
+                pairs.append(("__yq_style_{}__".format(hash_key(key)), 
v_node.style))
+            elif isinstance(v_node, (yaml.nodes.SequenceNode, 
yaml.nodes.MappingNode)) and v_node.flow_style is True:
+                pairs.append(("__yq_style_{}__".format(hash_key(key)), "flow"))
+        return OrderedDict(pairs)
+
+    def parse_unknown_tags(loader, tag_suffix, node):
+        if isinstance(node, yaml.nodes.ScalarNode):
+            return loader.construct_scalar(node)
+        elif isinstance(node, yaml.nodes.SequenceNode):
+            return construct_sequence(loader, node)
+        elif isinstance(node, yaml.nodes.MappingNode):
+            return construct_mapping(loader, node)
+
+    
OrderedLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, 
construct_mapping)
+    
OrderedLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_SEQUENCE_TAG, 
construct_sequence)
+    OrderedLoader.add_multi_constructor('', parse_unknown_tags)
+    return OrderedLoader
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq/parser.py new/yq-2.10.0/yq/parser.py
--- old/yq-2.8.1/yq/parser.py   1970-01-01 01:00:00.000000000 +0100
+++ new/yq-2.10.0/yq/parser.py  2019-12-23 05:06:54.000000000 +0100
@@ -0,0 +1,74 @@
+from __future__ import absolute_import, division, print_function, 
unicode_literals
+
+import sys, argparse, subprocess
+
+from .version import __version__
+
+# jq arguments that consume positionals must be listed here to avoid our 
parser mistaking them for our positionals
+jq_arg_spec = {"--indent": 1, "-f": 1, "--from-file": 1, "-L": 1, "--arg": 2, 
"--argjson": 2, "--slurpfile": 2,
+               "--argfile": 2, "--rawfile": 2, "--args": argparse.REMAINDER, 
"--jsonargs": argparse.REMAINDER}
+
+class Parser(argparse.ArgumentParser):
+    def print_help(self):
+        yq_help = argparse.ArgumentParser.format_help(self).splitlines()
+        print("\n".join(["usage: yq [options] <jq filter> [YAML file...]"] + 
yq_help[1:] + [""]))
+        try:
+            subprocess.check_call(["jq", "--help"])
+        except Exception:
+            pass
+
+def get_parser(program_name, description):
+    # By default suppress these help strings and only enable them in the 
specific programs.
+    yaml_output_help, yaml_roundtrip_help, width_help, indentless_help = 
(argparse.SUPPRESS, argparse.SUPPRESS,
+                                                                          
argparse.SUPPRESS, argparse.SUPPRESS)
+    xml_output_help, xml_dtd_help, xml_root_help = argparse.SUPPRESS, 
argparse.SUPPRESS, argparse.SUPPRESS
+    toml_output_help = argparse.SUPPRESS
+
+    if program_name == "yq":
+        current_language = "YAML"
+        yaml_output_help = "Transcode jq JSON output back into YAML and emit 
it"
+        yaml_roundtrip_help = """Transcode jq JSON output back into YAML and 
emit it.
+Preserve YAML tags and styles by representing them as extra items
+in their enclosing mappings and sequences while in JSON. This option
+is incompatible with jq filters that do not expect these extra items."""
+        width_help = "When using --yaml-output, specify string wrap width"
+        indentless_help = """When using --yaml-output, indent block style 
lists (sequences)
+with 0 spaces instead of 2"""
+    elif program_name == "xq":
+        current_language = "XML"
+        xml_output_help = "Transcode jq JSON output back into XML and emit it"
+        xml_dtd_help = "Preserve XML Document Type Definition (disables 
streaming of multiple docs)"
+        xml_root_help = "When transcoding back to XML, envelope the output in 
an element with this name"
+    elif program_name == "tq":
+        current_language = "TOML"
+        toml_output_help = "Transcode jq JSON output back into TOML and emit 
it"
+    else:
+        raise Exception("Unknown program name")
+
+    description = description.replace("yq", program_name).replace("YAML", 
current_language)
+    parser_args = dict(prog=program_name, description=description, 
formatter_class=argparse.RawTextHelpFormatter)
+    if sys.version_info >= (3, 5):
+        parser_args.update(allow_abbrev=False)  # required to disambiguate 
options listed in jq_arg_spec
+    parser = Parser(**parser_args)
+    parser.add_argument("--output-format", default="json", 
help=argparse.SUPPRESS)
+    parser.add_argument("--yaml-output", "--yml-output", "-y", 
dest="output_format", action="store_const", const="yaml",
+                        help=yaml_output_help)
+    parser.add_argument("--yaml-roundtrip", "--yml-roundtrip", "-Y", 
dest="output_format", action="store_const",
+                        const="annotated_yaml", help=yaml_roundtrip_help)
+    parser.add_argument("--width", "-w", type=int, help=width_help)
+    parser.add_argument("--indentless-lists", "--indentless", 
action="store_true", help=indentless_help)
+    parser.add_argument("--xml-output", "-x", dest="output_format", 
action="store_const", const="xml",
+                        help=xml_output_help)
+    parser.add_argument("--xml-dtd", action="store_true", help=xml_dtd_help)
+    parser.add_argument("--xml-root", help=xml_root_help)
+    parser.add_argument("--toml-output", "-t", dest="output_format", 
action="store_const", const="toml",
+                        help=toml_output_help)
+    parser.add_argument("--in-place", "-i", action="store_true", help="Edit 
files in place (no backup - use caution)")
+    parser.add_argument("--version", action="version", version="%(prog)s 
{version}".format(version=__version__))
+
+    for arg in jq_arg_spec:
+        parser.add_argument(arg, nargs=jq_arg_spec[arg], dest=arg, 
action="append", help=argparse.SUPPRESS)
+
+    parser.add_argument("jq_filter")
+    parser.add_argument("input_streams", nargs="*", type=argparse.FileType(), 
metavar="files", default=[sys.stdin])
+    return parser
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq/version.py new/yq-2.10.0/yq/version.py
--- old/yq-2.8.1/yq/version.py  2019-10-28 17:16:41.000000000 +0100
+++ new/yq-2.10.0/yq/version.py 2019-12-23 17:52:24.000000000 +0100
@@ -1 +1 @@
-__version__ = '2.8.1'
+__version__ = '2.10.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq.egg-info/PKG-INFO 
new/yq-2.10.0/yq.egg-info/PKG-INFO
--- old/yq-2.8.1/yq.egg-info/PKG-INFO   2019-10-28 17:16:45.000000000 +0100
+++ new/yq-2.10.0/yq.egg-info/PKG-INFO  2019-12-23 17:52:28.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: yq
-Version: 2.8.1
+Version: 2.10.0
 Summary: Command-line YAML/XML processor - jq wrapper for YAML/XML documents
 Home-page: https://github.com/kislyuk/yq
 Author: Andrey Kislyuk
@@ -31,20 +31,81 @@
         
             yq .foo.bar input.yml
         
-        By default, no conversion of ``jq`` output is done. Use the 
``--yaml-output``/``-y`` argument to convert it back into YAML::
+        By default, no conversion of ``jq`` output is done. Use the 
``--yaml-output``/``-y`` option to convert it back into YAML::
         
             cat input.yml | yq -y .foo.bar
         
-        Use the ``--width``/``-w`` argument to pass the line wrap width for 
string literals. All other command line arguments are
-        forwarded to ``jq``. ``yq`` forwards the exit code ``jq`` produced, 
unless there was an error in YAML parsing, in which case
-        the exit code is 1. See the `jq manual 
<https://stedolan.github.io/jq/manual/>`_ for more details on ``jq`` features 
and
-        options.
-        
-        YAML `tags <http://www.yaml.org/spec/1.2/spec.html#id2764295>`_ in the 
input are ignored (any nested data is treated as
-        untagged). Key order is preserved.
+        Mapping key order is preserved. By default, custom `YAML tags 
<http://www.yaml.org/spec/1.2/spec.html#id2764295>`_ and
+        `styles <https://yaml.org/spec/current.html#id2509255>`_ in the input 
are ignored. Use the ``--yaml-roundtrip``/``-Y``
+        option to preserve YAML tags and styles by representing them as extra 
items in their enclosing mappings and sequences
+        while in JSON::
+        
+            yq -Y .foo.bar input.yml
+        
+        Use the ``--width``/``-w`` option to pass the line wrap width for 
string literals. With ``-y/-Y``, files can be edited
+        in place like with ``sed -i``: ``yq -yi .foo=1 *.yml``. All other 
command line arguments are forwarded to ``jq``. ``yq``
+        forwards the exit code ``jq`` produced, unless there was an error in 
YAML parsing, in which case the exit code is 1.
+        See the `jq manual <https://stedolan.github.io/jq/manual/>`_ for more 
details on ``jq`` features and options.
         
         Because YAML treats JSON as a dialect of YAML, you can use yq to 
convert JSON to YAML: ``yq -y . < in.json > out.yml``.
         
+        Preserving tags and styles using the ``-Y`` (``--yaml-roundtrip``) 
option
+        
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        
+        The ``-Y`` option helps preserve custom `string styles 
<https://yaml-multiline.info/>`_ and
+        `tags <https://camel.readthedocs.io/en/latest/yamlref.html#tags>`_ in 
your document. For exmaple, consider the following
+        document (an `AWS CloudFormation 
<https://aws.amazon.com/cloudformation/>`_ template fragment)::
+        
+            Resources:
+              ElasticLoadBalancer:
+                Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
+                Properties:
+                  AvailabilityZones: !GetAZs ''
+                  Instances:
+                    - !Ref Ec2Instance1
+                    - !Ref Ec2Instance2
+                  Description: >-
+                    Load balancer for Big Important Service.
+        
+                    Good thing it's managed by this template.
+        
+        Passing this document through ``yq -y .Resources.ElasticLoadBalancer`` 
will drop custom tags, such as ``!Ref``,
+        and styles, such as the `folded <https://yaml-multiline.info/>`_ style 
of the ``Description`` field::
+        
+            Type: AWS::ElasticLoadBalancing::LoadBalancer
+            Properties:
+              AvailabilityZones: ''
+              Instances:
+                - Ec2Instance1
+                - Ec2Instance2
+              Description: 'Load balancer for Big Important Service.
+        
+                Good thing it''s managed by this template.'
+        
+        By contrast, passing it through ``yq -Y 
.Resources.ElasticLoadBalancer`` will preserve tags and styles::
+        
+            Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
+            Properties:
+              AvailabilityZones: !GetAZs ''
+              Instances:
+                - !Ref 'Ec2Instance1'
+                - !Ref 'Ec2Instance2'
+              Description: >-
+                Load balancer for Big Important Service.
+        
+                Good thing it's managed by this template.
+        
+        To accomplish this in ``-Y`` mode, yq carries extra metadata (mapping 
pairs and sequence values) in the JSON
+        representation of your document for any custom tags or styles that it 
finds. When converting the JSON back into YAML, it
+        parses this metadata, re-applies the tags and styles, and discards the 
extra pairs and values.
+        
+        .. warning ::
+        
+         The ``-Y`` option is incompatible with jq filters that do not expect 
the extra information injected into the document
+         to preserve the YAML formatting. For example, a jq filter that counts 
entries in the Instances array will come up with
+         4 entries instead of 2. A filter that expects all array entries to be 
mappings may break due to the presence of string
+         metadata keys. Check your jq filter for compatibility/semantic 
validity when using the ``-Y`` option.
+        
         XML support
         -----------
         ``yq`` also supports XML. The ``yq`` package installs an executable, 
``xq``, which
@@ -67,7 +128,7 @@
         Links
         -----
         * `Project home page (GitHub) <https://github.com/kislyuk/yq>`_
-        * `Documentation (Read the Docs) 
<https://yq.readthedocs.io/en/latest/>`_
+        * `Documentation <https://kislyuk.github.io/yq/>`_
         * `Package distribution (PyPI) <https://pypi.python.org/pypi/yq>`_
         * `Change log <https://github.com/kislyuk/yq/blob/master/Changes.rst>`_
         * `jq <https://stedolan.github.io/jq/>`_ - the command-line JSON 
processor utility powering ``yq``
@@ -80,16 +141,14 @@
         -------
         Licensed under the terms of the `Apache License, Version 2.0 
<http://www.apache.org/licenses/LICENSE-2.0>`_.
         
-        .. image:: https://img.shields.io/travis/kislyuk/yq.svg
-                :target: https://travis-ci.org/kislyuk/yq
+        .. image:: 
https://github.com/kislyuk/yq/workflows/Python%20package/badge.svg
+                :target: https://github.com/kislyuk/yq/actions
         .. image:: 
https://codecov.io/github/kislyuk/yq/coverage.svg?branch=master
                 :target: https://codecov.io/github/kislyuk/yq?branch=master
         .. image:: https://img.shields.io/pypi/v/yq.svg
                 :target: https://pypi.python.org/pypi/yq
         .. image:: https://img.shields.io/pypi/l/yq.svg
                 :target: https://pypi.python.org/pypi/yq
-        .. image:: https://readthedocs.org/projects/yq/badge/?version=latest
-                :target: https://yq.readthedocs.io/
         
 Platform: UNKNOWN
 Classifier: Intended Audience :: Developers
@@ -98,10 +157,10 @@
 Classifier: Operating System :: POSIX
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Provides-Extra: test
 Provides-Extra: toml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq.egg-info/SOURCES.txt 
new/yq-2.10.0/yq.egg-info/SOURCES.txt
--- old/yq-2.8.1/yq.egg-info/SOURCES.txt        2019-10-28 17:16:45.000000000 
+0100
+++ new/yq-2.10.0/yq.egg-info/SOURCES.txt       2019-12-23 17:52:28.000000000 
+0100
@@ -3,8 +3,14 @@
 README.rst
 setup.cfg
 setup.py
+test/bomb.yml
+test/cfn.yml
 test/test.py
 yq/__init__.py
+yq/compat.py
+yq/dumper.py
+yq/loader.py
+yq/parser.py
 yq/version.py
 yq.egg-info/PKG-INFO
 yq.egg-info/SOURCES.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yq-2.8.1/yq.egg-info/requires.txt 
new/yq-2.10.0/yq.egg-info/requires.txt
--- old/yq-2.8.1/yq.egg-info/requires.txt       2019-10-28 17:16:45.000000000 
+0100
+++ new/yq-2.10.0/yq.egg-info/requires.txt      2019-12-23 17:52:28.000000000 
+0100
@@ -1,6 +1,7 @@
 setuptools
 PyYAML>=3.11
 xmltodict>=0.11.0
+argcomplete>=1.8.1
 
 [test]
 coverage


Reply via email to