Skip to content

Commit

Permalink
git diff support
Browse files Browse the repository at this point in the history
- feat: entrypoint sphobjinv-textconv ([bskinn#295])
- test: add sphobjinv-textconv unittests offline and online
- test: add integration test. Demonstrate git diff objects.inv
- test: add pytest module with class to interact with git
- docs: add step by step guide to configure git. Both bash and python code examples
- docs: added sphobjinv-textconv API docs
  • Loading branch information
msftcangoblowm committed Aug 26, 2024
1 parent 7e76998 commit 19029ad
Show file tree
Hide file tree
Showing 17 changed files with 1,578 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
tests/resource/objects_mkdoc_zlib0.inv binary
tests/resource/objects_attrs.txt binary
*.inv binary diff=inv
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ and this project follows an extension of
fourth number represents an administrative maintenance release with no code
changes.

### [2.4.0] - 2024-08-26

#### Added

* Entrypoint sphobjinv-textconv ([#295])

#### Tests

* Unittests both offline and online
* Integration test to demonstrate git diff objects.inv
* add pytest module with class to interact with git

#### Documentation

* Added step by step guide to configure git. Both bash and python code examples
* Added sphobjinv-textconv API docs

### [2.3.1.1] - 2024-05-21

#### Tests
Expand Down
62 changes: 62 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,68 @@ def func(arglist, *, expect=0): # , suffix=None):
return func


@pytest.fixture() # Must be function scope since uses monkeypatch
def run_cmdline_textconv(monkeypatch):
"""Return function to perform command line exit code test."""
from sphobjinv.cli.core_textconv import main

def func(arglist, *, expect=0): # , suffix=None):
"""Perform the CLI exit-code test."""

# Assemble execution arguments
runargs = ["sphobjinv-textconv"]
runargs.extend(str(a) for a in arglist)

# Mock sys.argv, run main, and restore sys.argv
with monkeypatch.context() as m:
m.setattr(sys, "argv", runargs)

try:
main()
except SystemExit as e:
retcode = e.args[0]
ok = True
else:
ok = False

# Do all pytesty stuff outside monkeypatch context
assert ok, "SystemExit not raised on termination."

# Test that execution completed w/indicated exit code
assert retcode == expect, runargs

return func


@pytest.fixture() # Must be function scope since uses monkeypatch
def run_cmdline_no_checks(monkeypatch):
"""Return function to perform command line. So as to debug issues no tests."""
from sphobjinv.cli.core_textconv import main

def func(arglist, *, prog="sphobjinv-textconv"):
"""Perform the CLI exit-code test."""

# Assemble execution arguments
runargs = [prog]
runargs.extend(str(a) for a in arglist)

# Mock sys.argv, run main, and restore sys.argv
with monkeypatch.context() as m:
m.setattr(sys, "argv", runargs)

try:
main()
except SystemExit as e:
retcode = e.args[0]
is_system_exit = True
else:
is_system_exit = False

return retcode, is_system_exit

return func


@pytest.fixture(scope="session")
def decomp_cmp_test(misc_info, is_win, unix2dos):
"""Return function to confirm a decompressed file is identical to resource."""
Expand Down
164 changes: 164 additions & 0 deletions doc/source/cli/git_diff.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
.. Description of configure git diff support for inventory files
Integration -- git diff
========================

.. program:: git diff

|soi-textconv| converts .inv files to plain text sending the
output to |stdout|.

.. code-block:: shell
sphobjinv-textconv objects.inv
Which is equivalent to

.. code-block:: shell
sphobjinv convert plain objects.inv -
Convenience aside, why the redundant CLI command, |soi-textconv|?

To compare changes to a |objects.inv| file, :code:`git diff` won't
produce a useful result without configuration. And git only accepts a
CLI command with:

- one input, the INFILE path

- sends output to |stdout|

Usage
------

Initialize git
"""""""""""""""

.. code-block:: shell
git init
git config user.email [email protected]
git config user.name "a test"
Configure git
""""""""""""""

``git diff`` is really useful, , so it's time to configure git

Currently there is no CLI command to configure git for us.

In ``.git/config`` (or $HOME/.config/git/config) append,

.. code-block:: text
[diff "inv"]
textconv = [absolute path to venv bin folder]/sphobjinv-textconv
Note has one tab, not whitespace(s)

In ``.gitattributes`` append,

.. code-block:: text
*.inv binary diff=inv
Make one commit
""""""""""""""""

Commit these files:

- objects_attrs.inv

- objects_attrs.txt

- .gitattributes

.. code-block:: shell
git add .
git git commit --no-verify --no-gpg-sign -m "test textconv"
Make a change to ``objects_attrs.inv``
"""""""""""""""""""""""""""""""""""""""

By shell

.. code-block:: shell
URL="https://github.com/bskinn/sphobjinv/raw/main/tests/resource/objects_attrs.inv"
wget "$URL"
sphobjinv convert plain -qu "$URL" objects_attrs.txt
export APPEND_THIS="attrs.validators.set_cheat_mode py:function 1 api.html#$ -"
echo "$APPEND_THIS" >> objects_attrs.txt
sphobjinv convert zlib -qu objects_attrs.txt objects_attrs.inv
By python code

.. versionadded:: 2.4.0
Append a line to .inv (compressed) inventory

.. doctest:: append_a_line

>>> from pathlib import Path
>>> from sphobjinv import DataObjStr
>>> from sphobjinv.cli.load import import_infile
>>> from sphobjinv.cli.write import write_plaintext
>>>
>>> remote_url = (
... "https://github.com/bskinn/sphobjinv/"
... "raw/main/tests/resource/objects_attrs.inv"
... )
>>> cli_run(f'sphobjinv convert plain -qu {remote_url} objects_attrs.txt')
<BLANKLINE>
>>> path_dst_dec = Path('objects_attrs.txt')
>>> path_dst_cmp = Path('objects_attrs.inv')
>>> dst_dec_path = str(path_dst_dec)
>>> path_dst_dec.is_file()
True
>>> inv_0 = import_infile(dst_dec_path)
>>> obj_datum = DataObjStr(
... name="attrs.validators.set_cheat_mode",
... domain="py",
... role="function",
... priority="1",
... uri="api.html#$",
... dispname="-",
... )
>>> inv_0.objects.append(obj_datum)
>>> write_plaintext(inv_0, dst_dec_path)
>>> cli_run('sphobjinv convert -q zlib objects_attrs.txt objects_attrs.inv')
<BLANKLINE>
>>> path_dst_cmp.is_file()
True

Show the diff
""""""""""""""

.. code-block:: shell
git diff HEAD objects_attrs.inv 2>/dev/null
.. code-block:: text
diff --git a/objects.inv b/objects.inv
index 85189bd..65cc567 100644
--- a/objects.inv
+++ b/objects.inv
@@ -131,4 +131,5 @@ types std:doc -1 types.html Type Annotations
validators std:label -1 init.html#$ Validators
version-info std:label -1 api.html#$ -
why std:doc -1 why.html Why not…
+attrs.validators.set_cheat_mode py:function 1 api.html#$ -
The last line contains <whitespace><newline> rather than <newline>

The 2nd line changes every time

:code:`2>/dev/null` means suppress |stderr|

.. seealso::

To see the entire process, check out the integration test

``tests/test_cli_textconv_with_git.py``
7 changes: 7 additions & 0 deletions doc/source/cli/implementation/core-textconv.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.. Module API page for cli/core_textconv.py
sphobjinv.cli.core_textconv
===========================

.. automodule:: sphobjinv.cli.core_textconv
:members:
1 change: 1 addition & 0 deletions doc/source/cli/implementation/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ sphobjinv.cli (non-API)

convert
core
core-textconv
load
parser
paths
Expand Down
112 changes: 112 additions & 0 deletions doc/source/cli/textconv.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
.. Description of sphobjinv-textconv commandline usage
Command-Line Usage: |soi-textconv|
===================================

.. program:: |soi-textconv|

Terse syntax command to convert |objects.inv| to |stdout|. Extends
:code:`git diff`. Comparing against partially binary
|objects.inv| versions, produces useful results.

Rather than *These two binary files differ*

Unlike |soi|, |soi-textconv| coding style is ``adapt to survive``.
Regardless of what's thrown at it, does what it can.

Difference

- when an inventory file is piped in from |stdin|, specifying "-" is optional

- checks |stdin| even before parsing cli arguments

----

**Usage**

.. command-output:: sphobjinv-textconv --help
:ellipsis: 4

.. versionadded:: 2.4.0

.. seealso::

Step by step configuration, usage, and code samples

:doc:`git_diff`

**Positional Arguments**

.. option:: infile

Path (or URL, if :option:`--url` is specified) to file to be converted.

If passed as ``-``, |soi-textconv| will attempt import of a plaintext or JSON
inventory from |stdin| (incompatible with :option:`--url`).

**Flags**

.. option:: -h, --help

Display help message and exit.

.. option:: -u, --url

Treat :option:`infile` as a URL for download. Cannot be used when
:option:`infile` is passed as ``-``.

.. option:: -e, --expand

Expand any abbreviations in `uri` or `dispname` fields before writing to output;
see :ref:`here <syntax_shorthand>`.

**Examples**

Remote URL

.. code-block:: shell
export URL="https://github.com/bskinn/sphobjinv/raw/main/tests/resource/objects_attrs.inv"
sphobjinv-textconv "$URL"
Local URL

.. code-block:: shell
sphobjinv-textconv --url "file:///home/pepe/Downloads/objects.inv"
Piping in compressed inventories is not allowed

.. code-block:: shell
sphobjinv-textconv "-" < objects.inv
^^ BAD ^^

.. code-block:: shell
export URL="https://github.com/bskinn/sphobjinv/raw/main/tests/resource/objects_attrs.inv"
sphobjinv-textconv "-" < "$URL"
plain text

.. code-block:: shell
export URL="https://github.com/bskinn/sphobjinv/raw/main/tests/resource/objects_attrs.inv"
sphobjinv convert -uq plain "$URL" "-" | sphobjinv-textconv
JSON

.. code-block:: shell
sphobjinv-textconv < objects.json
Expanding `uri` or `dispname` fields

.. code-block:: shell
sphobjinv-textconv -e objects.inv
.. caution:: Caveat

When an inventory is piped in from stdin, ``-e`` option is ignored
Loading

0 comments on commit 19029ad

Please sign in to comment.