Skip to content

Commit e5ba8b6

Browse files
Stop writing a log file into the working directory (t38)
Stop writing a log file into the working directory
2 parents 6a2ede6 + 16c389e commit e5ba8b6

5 files changed

Lines changed: 33 additions & 19 deletions

File tree

‎.gitignore‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,6 @@ TSWLatexianTemp*
683683

684684

685685
.idea
686-
log
687686
**/_autosummary
688687
*.pdf
689688
/tex

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
- `in2lambda spec run SPEC` runs a YAML file of selectors over the frozen source: it says which blocks are questions, parts and solutions, which to ignore, what to strip off the front of each one, and which of the four filters lays the solutions out. It fills in the draft's fields with the markdown of the lines each was taken from, records the spec's name and hash in the log so a replay runs the same file, and reports every block it made nothing of. Running an edited spec over a draft it has already filled in is refused, as freezing a document that has changed is: `in2lambda source add --start-over` begins the draft again. Reading a spec needs pyyaml, which the `convert` extra now installs alongside panflute. See [the spec page](https://lambda-feedback.github.io/in2lambda/spec.html) for the selectors and layouts.
1313
- `in2lambda validate` checks a draft over as a whole and writes what it finds into it as a `report`: source blocks in no field and not marked ignore, two fields taken from the same lines, gaps in the numbering of the questions or their parts, parts nothing answers, and fields holding nothing. Each finding names the field and the lines it is about, so it can be acted on without reading the draft. Finding something is not a failure and the command still exits 0; the report is replaced by the next run of the checks and dropped by the next command that changes the draft, since it describes the draft as it stood.
1414
- `in2lambda build` writes the draft in this directory out as a Lambda Feedback set: one question per `qN.text` field, holding the parts written for it and the worked solutions, with the images those fields refer to under `media/`, as `in2lambda convert` writes a set - a field naming an image that is not beside the draft is refused saying which file is missing, since the checks read the draft and not the folder it is in, and a question's own solution written beside a solution for every part it has becomes a part of its own holding just that solution, as `convert` pairs them up. It is refused unless `in2lambda validate` has been run since the draft last changed - every command that changes one drops its report - and found nothing, and the refusal prints what the report says so it can be acted on without opening the draft. `in2lambda render` writes each question as a PDF instead, compiled as Lambda Feedback's own PDF generator compiles it, which needs pandoc and xelatex; it is gated on nothing, since looking at a draft is how what the checks found gets fixed. Both take `-o/--out`, as `convert` does.
15+
- Importing `in2lambda.katex_convert` no longer writes a file called `log` into the working directory. What it has to say about a converted expression goes to the `in2lambda.katex_convert` logger, which is silent unless the application configures logging.
1516
- The Python API is unchanged: `in2lambda.main.runner` and everything under `in2lambda.api` take the same arguments and return the same objects.

‎in2lambda/katex_convert/katex_convert.py‎

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,10 @@
88
import re
99
from pathlib import Path
1010

11-
# Create a logger object with a name and a level
12-
logger = logging.getLogger("log")
13-
logger.setLevel(logging.INFO)
14-
15-
# Create a file handler to write the messages to a file
16-
file_handler = logging.FileHandler("log", mode="w") # Clears log with every run
17-
file_handler.setLevel(logging.INFO)
18-
19-
# Create a formatter to format the messages
20-
formatter = logging.Formatter("%(message)s")
21-
22-
# Add the formatter to the file handler
23-
file_handler.setFormatter(formatter)
24-
25-
# Add the file handler to the logger
26-
logger.addHandler(file_handler)
11+
# No handler: one attached here wrote a file called `log` into whatever directory the
12+
# importing process happened to be run from. Where these messages go is the
13+
# application's to decide, by configuring the `in2lambda` logger or this child of it.
14+
logger = logging.getLogger("in2lambda.katex_convert")
2715

2816

2917
def latex_to_katex(latex_string: str) -> str:
@@ -123,8 +111,6 @@ def replace_functions(latex_string: str) -> str:
123111
Returns:
124112
The same LaTeX string with some commands replaced where necessary.
125113
"""
126-
logger.info("")
127-
128114
# replace the incompatible functions with their KaTeX equivalents using re.sub
129115
for old, new in unsupported_commands().items():
130116
if new is None: # Deleted rather than replaced; see delete_functions.

‎log‎

Whitespace-only changes.

‎tests/test_cli.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,34 @@ def test_old_form_fails_when_run_as_the_installed_command(
7575
assert not (tmp_path / "out").exists()
7676

7777

78+
def test_convert_leaves_only_what_it_writes(filters_dir: str, tmp_path) -> None:
79+
"""Converting in an empty directory leaves the input and the output and nothing else.
80+
81+
In a subprocess because importing the package is what used to leave a file behind:
82+
within pytest it happens once, before any test can chdir somewhere of its own.
83+
"""
84+
shutil.copy(os.path.join(filters_dir, "PartsSepSol", "example.tex"), tmp_path)
85+
86+
result = subprocess.run(
87+
[
88+
sys.executable,
89+
"-c",
90+
"from in2lambda.main import cli; cli()",
91+
"convert",
92+
"example.tex",
93+
"PartsSepSol",
94+
"-o",
95+
"out",
96+
],
97+
capture_output=True,
98+
text=True,
99+
cwd=tmp_path,
100+
)
101+
102+
assert result.returncode == 0, result.stdout + result.stderr
103+
assert {path.name for path in tmp_path.iterdir()} == {"example.tex", "out"}
104+
105+
78106
def test_completing_the_old_form_offers_the_subcommand() -> None:
79107
"""Completion resolves half-typed command lines, so the guard must not fire there.
80108

0 commit comments

Comments
 (0)