Adding upstream version 1.13.2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
277294eb9f
commit
0982975b25
6 changed files with 146 additions and 30 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,3 +1,15 @@
|
|||
## 1.13.2 - 2024-11-24
|
||||
|
||||
### Internal
|
||||
|
||||
* Read the version from the git tag using setuptools-scm
|
||||
|
||||
## 1.13.0 - 2024-11-23
|
||||
|
||||
### Features
|
||||
|
||||
* Add `\pipe_once` / `\|` commands for sending output to a command
|
||||
|
||||
## 1.12.4 - 2024-11-11
|
||||
|
||||
### Bug Fixes
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
__version__ = "1.12.4"
|
||||
import importlib.metadata
|
||||
|
||||
__version__ = importlib.metadata.version("litecli")
|
||||
|
|
|
@ -472,6 +472,7 @@ class LiteCli(object):
|
|||
result_count += 1
|
||||
mutating = mutating or is_mutating(status)
|
||||
special.unset_once_if_written()
|
||||
special.unset_pipe_once_if_written()
|
||||
except EOFError as e:
|
||||
raise e
|
||||
except KeyboardInterrupt:
|
||||
|
@ -658,6 +659,7 @@ class LiteCli(object):
|
|||
self.log_output(line)
|
||||
special.write_tee(line)
|
||||
special.write_once(line)
|
||||
special.write_pipe_once(line)
|
||||
|
||||
if fits or output_via_pager:
|
||||
# buffering
|
||||
|
@ -824,7 +826,7 @@ class LiteCli(object):
|
|||
|
||||
|
||||
@click.command()
|
||||
@click.option("-V", "--version", is_flag=True, help="Output litecli's version.")
|
||||
@click.version_option(__version__, "-V", "--version")
|
||||
@click.option("-D", "--database", "dbname", help="Database to use.")
|
||||
@click.option(
|
||||
"-R",
|
||||
|
@ -857,7 +859,6 @@ class LiteCli(object):
|
|||
def cli(
|
||||
database,
|
||||
dbname,
|
||||
version,
|
||||
prompt,
|
||||
logfile,
|
||||
auto_vertical_output,
|
||||
|
@ -874,11 +875,6 @@ def cli(
|
|||
- litecli lite_database
|
||||
|
||||
"""
|
||||
|
||||
if version:
|
||||
print("Version:", __version__)
|
||||
sys.exit(0)
|
||||
|
||||
litecli = LiteCli(
|
||||
prompt=prompt,
|
||||
logfile=logfile,
|
||||
|
|
|
@ -21,7 +21,10 @@ from litecli.packages.prompt_utils import confirm_destructive_query
|
|||
use_expanded_output = False
|
||||
PAGER_ENABLED = True
|
||||
tee_file = None
|
||||
once_file = once_file_args = written_to_once_file = None
|
||||
once_file = None
|
||||
written_to_once_file = None
|
||||
pipe_once_process = None
|
||||
written_to_pipe_once_process = False
|
||||
favoritequeries = FavoriteQueries(ConfigObj())
|
||||
|
||||
|
||||
|
@ -376,9 +379,12 @@ def write_tee(output):
|
|||
aliases=("\\o", "\\once"),
|
||||
)
|
||||
def set_once(arg, **_):
|
||||
global once_file_args
|
||||
|
||||
once_file_args = parseargfile(arg)
|
||||
global once_file, written_to_once_file
|
||||
try:
|
||||
once_file = open(**parseargfile(arg))
|
||||
except (IOError, OSError) as e:
|
||||
raise OSError("Cannot write to file '{}': {}".format(e.filename, e.strerror))
|
||||
written_to_once_file = False
|
||||
|
||||
return [(None, None, None, "")]
|
||||
|
||||
|
@ -386,26 +392,66 @@ def set_once(arg, **_):
|
|||
@export
|
||||
def write_once(output):
|
||||
global once_file, written_to_once_file
|
||||
if output and once_file_args:
|
||||
if once_file is None:
|
||||
try:
|
||||
once_file = open(**once_file_args)
|
||||
except (IOError, OSError) as e:
|
||||
once_file = None
|
||||
raise OSError("Cannot write to file '{}': {}".format(e.filename, e.strerror))
|
||||
|
||||
if output and once_file:
|
||||
click.echo(output, file=once_file, nl=False)
|
||||
click.echo("\n", file=once_file, nl=False)
|
||||
once_file.flush()
|
||||
written_to_once_file = True
|
||||
|
||||
|
||||
@export
|
||||
def unset_once_if_written():
|
||||
"""Unset the once file, if it has been written to."""
|
||||
global once_file, once_file_args, written_to_once_file
|
||||
global once_file, written_to_once_file
|
||||
if once_file and written_to_once_file:
|
||||
once_file.close()
|
||||
once_file = once_file_args = written_to_once_file = None
|
||||
once_file = written_to_once_file = None
|
||||
|
||||
|
||||
@special_command("\\pipe_once", "\\| command", "Send next result to a subprocess.", aliases=("\\|",))
|
||||
def set_pipe_once(arg, **_):
|
||||
global pipe_once_process, written_to_pipe_once_process
|
||||
pipe_once_cmd = shlex.split(arg)
|
||||
if len(pipe_once_cmd) == 0:
|
||||
raise OSError("pipe_once requires a command")
|
||||
written_to_pipe_once_process = False
|
||||
pipe_once_process = subprocess.Popen(
|
||||
pipe_once_cmd,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
bufsize=1,
|
||||
encoding="UTF-8",
|
||||
universal_newlines=True,
|
||||
)
|
||||
return [(None, None, None, "")]
|
||||
|
||||
|
||||
@export
|
||||
def write_pipe_once(output):
|
||||
global pipe_once_process, written_to_pipe_once_process
|
||||
if output and pipe_once_process:
|
||||
try:
|
||||
click.echo(output, file=pipe_once_process.stdin, nl=False)
|
||||
click.echo("\n", file=pipe_once_process.stdin, nl=False)
|
||||
except (IOError, OSError) as e:
|
||||
pipe_once_process.terminate()
|
||||
raise OSError("Failed writing to pipe_once subprocess: {}".format(e.strerror))
|
||||
written_to_pipe_once_process = True
|
||||
|
||||
|
||||
@export
|
||||
def unset_pipe_once_if_written():
|
||||
"""Unset the pipe_once cmd, if it has been written to."""
|
||||
global pipe_once_process, written_to_pipe_once_process
|
||||
if written_to_pipe_once_process:
|
||||
(stdout_data, stderr_data) = pipe_once_process.communicate()
|
||||
if len(stdout_data) > 0:
|
||||
print(stdout_data.rstrip("\n"))
|
||||
if len(stderr_data) > 0:
|
||||
print(stderr_data.rstrip("\n"))
|
||||
pipe_once_process = None
|
||||
written_to_pipe_once_process = False
|
||||
|
||||
|
||||
@special_command(
|
||||
|
|
|
@ -4,10 +4,8 @@ dynamic = ["version"]
|
|||
description = "CLI for SQLite Databases with auto-completion and syntax highlighting."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.7"
|
||||
license = {text = "BSD"}
|
||||
authors = [
|
||||
{name = "dbcli", email = "litecli-users@googlegroups.com"}
|
||||
]
|
||||
license = { text = "BSD" }
|
||||
authors = [{ name = "dbcli", email = "litecli-users@googlegroups.com" }]
|
||||
urls = { "homepage" = "https://github.com/dbcli/litecli" }
|
||||
dependencies = [
|
||||
"cli-helpers[styles]>=2.2.1",
|
||||
|
@ -19,9 +17,15 @@ dependencies = [
|
|||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools >= 61.0"]
|
||||
requires = [
|
||||
"setuptools>=64.0",
|
||||
"setuptools-scm>=8;python_version>='3.8'",
|
||||
"setuptools-scm<8;python_version<'3.8'",
|
||||
]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools_scm]
|
||||
|
||||
[project.scripts]
|
||||
litecli = "litecli.main:cli"
|
||||
|
||||
|
@ -42,8 +46,5 @@ exclude = ["screenshots", "tests*"]
|
|||
[tool.setuptools.package-data]
|
||||
litecli = ["liteclirc", "AUTHORS"]
|
||||
|
||||
[tool.setuptools.dynamic]
|
||||
version = {attr = "litecli.__version__"}
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 140
|
||||
|
|
59
tests/test_special_iocommands.py
Normal file
59
tests/test_special_iocommands.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
import os
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
|
||||
import litecli.packages.special
|
||||
|
||||
|
||||
def test_once_command():
|
||||
with pytest.raises(TypeError):
|
||||
litecli.packages.special.execute(None, ".once")
|
||||
|
||||
with pytest.raises(OSError):
|
||||
litecli.packages.special.execute(None, ".once /proc/access-denied")
|
||||
|
||||
litecli.packages.special.write_once("hello world") # write without file set
|
||||
# keep Windows from locking the file with delete=False
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
litecli.packages.special.execute(None, ".once " + f.name)
|
||||
litecli.packages.special.write_once("hello world")
|
||||
if os.name == "nt":
|
||||
assert f.read() == b"hello world\r\n"
|
||||
else:
|
||||
assert f.read() == b"hello world\n"
|
||||
|
||||
litecli.packages.special.execute(None, ".once -o " + f.name)
|
||||
litecli.packages.special.write_once("hello world line 1")
|
||||
litecli.packages.special.write_once("hello world line 2")
|
||||
f.seek(0)
|
||||
if os.name == "nt":
|
||||
assert f.read() == b"hello world line 1\r\nhello world line 2\r\n"
|
||||
else:
|
||||
assert f.read() == b"hello world line 1\nhello world line 2\n"
|
||||
# delete=False means we should try to clean up
|
||||
try:
|
||||
if os.path.exists(f.name):
|
||||
os.remove(f.name)
|
||||
except Exception as e:
|
||||
print(f"An error occurred while attempting to delete the file: {e}")
|
||||
|
||||
|
||||
def test_pipe_once_command():
|
||||
with pytest.raises(IOError):
|
||||
litecli.packages.special.execute(None, "\\pipe_once")
|
||||
|
||||
with pytest.raises(OSError):
|
||||
litecli.packages.special.execute(None, "\\pipe_once /proc/access-denied")
|
||||
|
||||
if os.name == "nt":
|
||||
litecli.packages.special.execute(None, '\\pipe_once python -c "import sys; print(len(sys.stdin.read().strip()))"')
|
||||
litecli.packages.special.write_pipe_once("hello world")
|
||||
litecli.packages.special.unset_pipe_once_if_written()
|
||||
else:
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
litecli.packages.special.execute(None, "\\pipe_once tee " + f.name)
|
||||
litecli.packages.special.write_pipe_once("hello world")
|
||||
litecli.packages.special.unset_pipe_once_if_written()
|
||||
f.seek(0)
|
||||
assert f.read() == b"hello world\n"
|
Loading…
Add table
Reference in a new issue