Skip to content

Commit b775ff9

Browse files
Keep the pre-2.0 command line working as an alias (t47)
Keep the pre-2.0 command line working as an alias
2 parents 6699c53 + 5810a01 commit b775ff9

4 files changed

Lines changed: 37 additions & 17 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# Changelog
22

3-
## 2.0.0
3+
## 1.1.0
44

5-
- Converting a document is now `in2lambda convert FILE FILTER`, with the same options as before (`-o/--out`, `-a/--answers`). Scripts and Docker invocations that run `in2lambda FILE FILTER` need the extra word.
6-
- `in2lambda FILE FILTER` exits with an error naming the command to run instead, rather than printing its usage and exiting successfully.
7-
- beartype is now `^0.22`. At 0.20.0 and below its import hook leaves `cli` a plain function rather than a group, so the new command line either fails to import or runs `convert` whatever the arguments; 0.20.1 is the first version that works.
5+
- Converting a document is now `in2lambda convert FILE FILTER`, with the same options as before (`-o/--out`, `-a/--answers`). `in2lambda FILE FILTER` still converts the file, printing one line to stderr naming the `in2lambda convert` command to run instead, so scripts and Docker invocations written before this keep working. A first argument that is neither a command nor a file is refused with that same line, rather than printing the usage and exiting successfully.
6+
- beartype is now `^0.22`. At 0.20.0 and below its import hook leaves `cli` a plain function rather than a group, so the command line either fails to import or runs `convert` whatever the arguments; 0.20.1 is the first version that works.
87
- `in2lambda source add FILE` freezes a document: it converts .docx and .tex to markdown beside the file, and writes a `FILE.draft.json` beside it, holding the markdown's hash and every block in it with the lines it spans, so that another tool can quote the source by line range. The draft is named after the source, so a folder holding a term's worth of sheets holds a draft for each. `in2lambda source show` prints that markdown numbered with the block ids. Freezing a file that has changed since is refused unless `--start-over` says to discard the draft, and so is showing one, since its block ids would name lines they are not the ids of. Both need pandoc and the `convert` extra, as `convert` does.
98
- A draft now holds a `log` of every command that changed it and a `fields` map of what those commands wrote, each field recording which layer wrote it (1 a spec, 2 a predicate, 3 a line range, 4 a literal), the source ranges it was copied from, whether it has been edited and by whom. `in2lambda draft mark ignore BLOCK` is the first such command, and `in2lambda draft replay` rebuilds the draft from the frozen markdown and the log, refusing unless what it builds is the draft that is there, byte for byte. A draft written before this has no `log` in it and is refused as one nothing here wrote; `in2lambda source add --start-over` freezes the document again.
109
- A draft is filled in by `in2lambda draft question add`, `in2lambda draft part add QUESTION` and `in2lambda draft question solution QUESTION`. Each takes `--text` to copy the wording out of the frozen source, as a block id such as `b3` or as lines such as `s10:14`, or `--literal TEXT` where the source does not say it in a form the field can take, which records the field as edited and written by layer 4 rather than 3. Question and part numbers are worked out from the fields already written rather than given, so a replay arrives at the same ids. `in2lambda draft split block BLOCK AT` cuts a block the parser made one of two things into `b3a` and `b3b`, so that each half can be quoted on its own. A command writing a field that is already written, or quoting lines another field was taken from, is refused: the first naming the field, the second naming both.

‎in2lambda/main.py‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import getpass
1010
import importlib
11+
import os
1112
import shlex
1213
import warnings
1314
from collections.abc import Callable # Rather than typing's, which beartype warns on.
@@ -178,17 +179,23 @@ def runner(
178179

179180

180181
class _Cli(click.RichGroup):
181-
"""The in2lambda group, which says what to run when given the pre-2.0 command line."""
182+
"""The in2lambda group, which says what to run when given the old command line."""
182183

183184
def resolve_command(self, ctx, args): # type: ignore[no-untyped-def]
184-
"""Fail with the new command line rather than click's handling of an unknown name.
185+
"""Run ``convert`` for the old form, and name it for a first argument that is neither.
185186
186187
Click resolves a first argument starting with ``/`` or ``.`` by printing the
187188
group's help and exiting successfully, so `in2lambda /path/to/questions.tex
188189
PartsSepSol` would look like it had worked while converting nothing.
189190
"""
190191
# Shell completion resolves partial command lines, and must not raise.
191192
if not ctx.resilient_parsing and self.get_command(ctx, args[0]) is None:
193+
if os.path.isfile(args[0]):
194+
click.echo(
195+
f"in2lambda FILE FILTER is the old form. Run: in2lambda convert {shlex.join(args)}",
196+
err=True,
197+
)
198+
return super().resolve_command(ctx, ["convert", *args])
192199
raise click.UsageError(
193200
f"in2lambda no longer takes a file directly. Run: in2lambda convert {shlex.join(args)}"
194201
)

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "in2lambda"
3-
version = "2.0.0"
3+
version = "1.1.0"
44
description = "Converts content ready for import into Lambda Feedback"
55
authors = []
66
license = "MIT"

‎tests/test_cli.py‎

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""What the command line does with the current and the pre-2.0 form."""
1+
"""What the command line does with the current and the old form."""
22

33
import os
44
import shutil
@@ -25,10 +25,10 @@ def test_convert_writes_the_set(filters_dir: str, tmp_path) -> None:
2525

2626

2727
@pytest.mark.parametrize("path", ["example.tex", "./example.tex", "ABSOLUTE"])
28-
def test_old_form_fails_and_names_convert(
28+
def test_old_form_converts_with_a_deprecation_line(
2929
path: str, filters_dir: str, monkeypatch, tmp_path
3030
) -> None:
31-
"""The pre-2.0 form errors out whatever the file path looks like.
31+
"""The old form converts whatever the file path looks like, saying so on stderr.
3232
3333
A path starting with ``/`` or ``.`` used to make click print the help and exit 0,
3434
so every script passing a full path appeared to succeed without converting anything.
@@ -42,12 +42,12 @@ def test_old_form_fails_and_names_convert(
4242

4343
result = CliRunner().invoke(cli, [path, "PartsSepSol"])
4444

45-
assert result.exit_code != 0
46-
assert "in2lambda convert" in result.output
47-
assert not (tmp_path / "out").exists()
45+
assert result.exit_code == 0, result.output
46+
assert "in2lambda FILE FILTER is the old form" in result.stderr
47+
assert (tmp_path / "out" / "set.zip").exists()
4848

4949

50-
def test_old_form_fails_when_run_as_the_installed_command(
50+
def test_old_form_works_when_run_as_the_installed_command(
5151
filters_dir: str, tmp_path
5252
) -> None:
5353
"""The same holds for ``cli()``, which is what the installed command runs.
@@ -70,9 +70,23 @@ def test_old_form_fails_when_run_as_the_installed_command(
7070
env={**os.environ, "COLUMNS": "200"},
7171
)
7272

73-
assert result.returncode != 0
74-
assert "in2lambda convert" in result.stdout + result.stderr
75-
assert not (tmp_path / "out").exists()
73+
assert result.returncode == 0, result.stdout + result.stderr
74+
assert "in2lambda FILE FILTER is the old form" in result.stderr
75+
assert "old form" not in result.stdout
76+
assert (tmp_path / "out" / "set.zip").exists()
77+
78+
79+
def test_first_argument_that_is_neither_still_names_convert(
80+
monkeypatch, tmp_path
81+
) -> None:
82+
"""A first argument that is neither a subcommand nor a file is refused."""
83+
monkeypatch.setenv("COLUMNS", "200") # So the message is not wrapped mid-sentence.
84+
monkeypatch.chdir(tmp_path)
85+
86+
result = CliRunner().invoke(cli, ["missing.tex", "PartsSepSol"])
87+
88+
assert result.exit_code != 0
89+
assert "in2lambda convert" in result.output
7690

7791

7892
def test_convert_leaves_only_what_it_writes(filters_dir: str, tmp_path) -> None:

0 commit comments

Comments
 (0)